The ZeroMQ binding can be combined with Ring Buffer Channels and the LMAX Disruptor to create low-latency processing engines. Consider the following topology where a consumer receives events from one channel, processes them and subsequently invokes another service that in turn publishes an output event to a second channel:
If the two channels
In this model, messages are
The above topology is configured to use ring buffer channels as follows:
Code Block | ||||
---|---|---|---|---|
| ||||
<composite ...>
<channel name="IncomingChannel" type="ring.buffer">
<f3:binding.zeromq addresses="192.0.2:2024"/>
</channel>
<channel name="OutgoingChannel" type="ring.buffer">
<f3:binding.zeromq addresses="190.0.1:2024"/>
</channel>
<component name="Component1">
<implementation.java class="..."/>
<consumer name="channel" source="IncomingChannel"/>
</component>
<component name="Component1">
<implementation.java class="..."/>
<producer name="channel" target="OutgoingChannel"/>
</component>
</composite>
|
At runtime, the above composite results in the following:
A message is read from a ZeroMQ socket on a thread 1 and placed in a ring buffer slot
(Disruptor) slot. The business logic runs on a second thread, which receives the message from the ring buffer (Disruptor). When processing is complete, a business logic component publishes the output event to the second channel which results it being placed in an outgoing ring buffer slot. A third thread responsible for dispatching messages over a ZeroMQ socket receives the output event and publishes it.
This channel architecture can be applied to a number of use cases which require fast (low-latency) and predictable (limited GC activity) performance. For an in-depth example, see the FastQuote sample.