Staged event-driven architecture (SEDA) is an architecture style that deals with this sort of
processing situation. In SEDA, you dampen the load on components of the architecture by staging it in
queues, and let advance only what the components downstream can handle. Put another way, imagine
video processing. If you ran a site with a million users uploading video that in turn needed to be
transcoded and you only had 10 servers, your system would fail if your system attempted to process each
video as soon as it received the uploaded video. Transcoding can take hours and pegs a CPU (or multiple
CPUs!) while it works. The most sensible thing to do would be to store the file and then, as capacity
permits, process each one. In this way, the load on the nodes that handle transcoding is managed.
There's always only enough work to keep the machine humming, but not overrun.
Similarly, no processing system (such as an ESB) can deal with a million records at once efficiently.
Strive to decompose bigger events and messages into smaller ones. Let's imagine a hypothetical solution
designed to accommodate a drop of batch files representing hourly sales destined for fulfillment. The
batch files are dropped onto a mount that Spring Integration is monitoring. Spring Integration kicks off
processing as soon as it sees a new file. Spring Integration tells Spring Batch about the file and launches
a Spring Batch job asynchronously.
Spring Batch reads the file, transforms the records into objects, and writes the output to a JMS topic
with a key correlating the original batch to the JMS message. Naturally, this takes half a day to get done,
but it does get done. Spring Integration, completely unaware that the job it started half a day ago is now
finished, begins popping messages off the topic, one by one. Processing to fulfill the records would
begin. Simple processing involving multiple components might begin on the ESB.
If fulfillment is a long-lived process with a long-lived, conversational state involving many actors,
perhaps the fulfillment for each record could be farmed to a BPM engine. The BPM engine would thread
together the different actors and work lists, allow work to continue over the course of days instead of the
small millisecond timeframes Spring Integration is more geared to. In this example, you used Spring
Batch as a springboard to dampen the load for components downstream. In this case, the component
downstream was again a Spring Integration process that took the work and set it up to be funneled into a
BPM engine where final processing could begin.
To learn more about invoking a Spring Batch job, please see Chapter 9.
You want to expose an interface to clients of your service, without betraying the fact that your service is
implemented in terms of messaging middleware.
Use a gateway—a pattern from the classic book Enterprise Integration Patterns by Gregor Hohpe and
Bobby Woolf (Addison-Wesley, 2004 ) that enjoys rich support in Spring Integration.
How It Works
A gateway is a distinct animal, similar to a lot of other patterns but ultimately different enough to
warrant its own consideration. You used adapters in previous examples to enable two systems to speak
in terms of foreign, loosely coupled, middleware components. This foreign component can be anything:
the file system, JMS queues/topics, Twitter, and so on.