I'm excited to announce the release of Fabric3 2.0. This milestone
introduces a number of new features. In particular, a major theme of the 2.0 release is
creating a platform that brings service-oriented and event-based design closer
together.
In this post, I will briefly touch on how Fabric3 does this and
also identify some of the other important features in this release.
Event-Based Systems
The area we invested in most heavily for the Fabric3 2.0 release is improving support for building event-based systems. Martin Thompson has given an excellent presentation on event-based architectures. Peter Lawrey and Martin Fowler have also written very nice synopses here and here.
Fabric3 already has a rich dependency-injection model for
event-sourced (pub/sub) interactions based on the concept of channels.
In this release we have significantly refactored the Fabric3 internals to
accommodate custom channels and low-latency requirements.
Now it is possible to plugin alternative channel implementations
based on application requirements. One out-of-the-box channel type we have
added is the ring buffer channel based on the LMAX Disruptor. This
provides extremely low-latency, lock-free pub/sub capabilities:
We also have plans in the future to add more specialty channel
types. For example, one based on coalescing buffers that is capable of dropping older unprocessed messages as newer ones arrive.
Ring buffer channels can be bound to transports such as
ZeroMQ using simple configuration. This makes it possible to develop performant
architectures using straightforward Java with no boilerplate API code:
For complete example, checkout the FastQuote trading
platform sample.
Low-Latency Systems
One knock against middleware in general and dependency
injection-based platforms in particular is that they introduce overhead during
processing by proxying references to injected instances. Fabric3 has always had
the ability to optimize wiring to perform direct (i.e. proxy-less) injection
for local services. This means a local service invocation is a Java method
invocation with no runtime intervention. Using this approach, we are able to achieve microsecond processing times for fairly complex tasks such as foreign exchange rate streaming.
In Fabric3 2.0 we took this concept further and applied it to
channel injection. In Fabric3, channels are strongly-typed and represented by
Java interfaces. At runtime, Fabric3 creates a proxy implementing the
interface, which is then injected on a component that publishes events to the
channel. By default, Fabric3 uses JDK proxies. For many applications, JDK
proxies are sufficient.
However, for low latency systems, JDK proxies introduce relatively
significant overhead. Perhaps more importantly, they create garbage as
invocation parameters are wrapped in an array. When messages are processed at
high volume in a system, the garbage resulting from the creation of parameter
arrays can lead to excessive GC pauses, which negatively impacts latency.
Our solution to this problem is to use bytecode generation (via
the ASM library) to implement the channel interface dynamically. The generated
implementation directly calls into the Fabric3 channel infrastructure without
using reflection or wrapping parameters. This results in garbage-free
invocations that are as fast as handwritten code. In the next release we plan
to go further and combine this with support for zero-copy message passing to
ZeroMQ.
High Performance Logging
After working with a number of clients, we found a major
bottleneck in many applications was logging. Part of the problem is that
applications often log too much information. In fact, logging in the traditional
sense is probably not necessary for many event-based systems, but that’s a
subject for another blog.
Another culprit is the logging subsystem itself: most third-party
logging implementations perform poorly in highly concurrent scenarios even
when they support asynchronous writes. This is because the logging
implementations are often subject to contention when placing messages in a
queue that is read by a background thread persisting to disk. In addition, we
have seen logging implementations produce a fair amount of garbage leading to
unacceptable CG pauses.
To alleviate these problems, we re-wrote the Fabric3 logging
framework to take advantage of the Disruptor for asynchronous writes and
bytecode generation to provide high-performance, garbage-free operation. You
can read more about it here.
Standards: SCA Conformance and JAX-RS 2.0 Support
One of Fabric3’s advantages with respect to proprietary Enterprise
Service Bus products and integration platforms is that it is standards-based from the
ground up. In this release we expanded our standards support to cover 100%
conformance with the OASIS SCA Assembly, Policy, WS Binding and Spring
Specifications. This includes all mandatory and optional features. In this
context it is also noteworthy that we upgraded our support for RESTful Web
Services to JAX-RS 2.0.
Get Started with Fabric3
To get started with Fabric3 2.0, try the sample applications, which contain all you need to get up and running with a cluster
installation in less than five minutes.
Also, watch this space as I discuss these new features in depth and
how they are being employed by our users to build innovative applications.
No comments:
Post a Comment