Dies ist keine Tirade gegen ESB. Ich sage nicht, dass ESBs
Die einzige Behauptung, die ich aufstelle, ist die, dass Sie - wenn Sie an der Umsetzung von Integrationsmustern interessiert sind - dies sicherlich mit viel weniger erreichen können. Und wie immer gilt: Weniger ist eindeutig mehr. Sie brauchen nicht immer eine monumentale Lösung, um ein Integrationsproblem zu lösen. Spring Integration und Camel sind wunderbare alternative Lösungen, die weitaus weniger aufdringlich sind. Das bedeutet nicht, dass alles rosig und sonnig ist. Es gibt sicherlich noch einiges zu wünschen übrig. Eines der Dinge, die ich bei Spring Integration vermisse, ist eine einfache Möglichkeit, eine garantierte Nachrichtenzustellung zu erreichen, und darum geht es in diesem Beitrag. Channels Eine der wichtigsten Abstraktionen von Spring Integration ist ein Channel. Betrachten Sie ihn als eine Warteschlange, die nicht notwendigerweise von einer - nun ja - Warteschlange unterstützt wird. Es ist einfach der Ort, an dem Sie eine Nachricht übergeben oder empfangen, ohne dass Sender und Empfänger notwendigerweise von der Existenz des jeweils anderen wissen. Wenn der Empfänger die Nachricht empfängt, kann diese Nachricht aus einem Puffer gezogen werden, der intern im Kanal aufbewahrt wird (wie bei einem QueueChannel), sie kann aber auch auf synchrone Weise zugestellt werden, und zwar von demselben Thread, der sie an den Kanal gesendet hat (wie bei einem DirectChannel). Aus der Sicht des Empfängers ist das alles dasselbe.
[caption id="attachment_3712" align="alignnone" width="572"]
Abstraktionen des Spring-Integrationskanals[/caption]
Wenn Sie mit einem Kanal arbeiten, der von einer speicherinternen BlockingQueue unterstützt wird, haben Sie ein gewisses Maß an Zuverlässigkeit. Sie wissen, dass die Nachricht mindestens einmal, höchstens einmal, zugestellt wird und dass diese Reihenfolge erhalten bleibt, aber
[caption id="attachment_3709" align="alignnone" width="354"]
Nachrichtenverlust in regulären Kanälen im Vergleich zu KahaChannel[/caption]
Idempotenz als Rettung?
Sie könnten argumentieren, dass Sie einfach alle Ihre Nachrichten wiedergeben könnten und - solange die Empfänger oder Zwischenstationen alle idempotente Empfänger sind - alles gut funktionieren wird, aber da bin ich anderer Meinung. Zunächst einmal möchten Sie nicht Ihren gesamten Nachrichtenverlauf beim Systemstart wiedergeben. Sie brauchen also wahrscheinlich einen Mechanismus, der verhindert, dass Nachrichten, die bereits die gesamte Kette der Nachrichtenbehandler durchlaufen haben, erneut gesendet werden. Wenn der idempotente Empfänger der einzige Trick ist, den Sie in petto haben, machen Sie sich selbst verdammt viel Arbeit, und das macht Ihr Leben nicht einfacher.
<si:channel id="inboxl">
<si:queue capacity="1101"/>
</si:channel>
Dann können Sie Ihr System nur noch ein wenig zuverlässiger machen, indem Sie das hier als Ersatz einbauen:
<bean id="inbox" class="nl.flotsam.spring.integration.kaha.KahaChannelFactory">
<property name="directory" value="..."/>
</bean>
Das obige Beispiel verwendet die KahaChannelFactory zur Erstellung einer Instanz. Das ist keine Voraussetzung. Sie können sie auch direkt konstruieren, indem Sie eine Instanz von KahaChannel erstellen und die Parameter als Konstruktorargumente übergeben. Dann entspricht der Name des darunter konstruierten Containers jedoch nicht automatisch der ID der Bean. Leistung Das Ersetzen eines speicherbasierten Kanals durch einen plattenbasierten Kanal mit zuverlässigen Liefergarantien hat natürlich seinen Preis. Der Leistungsverlust ist jedoch nicht unbedingt groß. Es hängt alles von der Größe und Komplexität Ihrer Nachrichten ab. Wenn Ihre Nachrichten kaum Daten enthalten, dann ist der Nachteil ziemlich gering: 10.000 Nachrichten durch einen In-Memory-Kanal zu pumpen, dauerte auf meinem System 3,2 Sekunden. Die gleichen Nachrichten durch einen KahaChannel zu schicken, dauerte nur 4,3 Sekunden. Rechnen Sie selbst nach. Kodierung von Nachrichten Um den KahaChannel wirklich zu einem zuverlässigen Kanal zu machen, der einen Absturz übersteht, müssen die Nachrichten natürlich gespeichert werden. Leider definiert Spring Integration noch keine Abstraktion für die Kodierung und Dekodierung von Nachrichten. Die Kaha-Abstraktionen ermöglichen die Kodierung auf DataOutput und die Dekodierung von DataInput, so dass letztendlich alles auf etwas abgebildet werden muss, das diese Abstraktionen unterstützt. Anstatt zu versuchen, die ultimative Art der Kodierung und Dekodierung einer Nachricht selbst zu implementieren (falls es so etwas überhaupt gibt), vertritt der KahaChannel im Grunde den Standpunkt, dass es an Ihnen liegt, einen vernünftigen Codec bereitzustellen. Und zu diesem Zweck definiert er seine eigene Nachrichtencodec-Schnittstelle:
public interface MessageCodec<T> {
void encode(Nachricht<T> value, DataOutput out) throws IOException;
Nachricht<T> decode(DataInput in) throws IOException;
}
Es wird jedoch auch ein eigener SimpleMessageCodec mitgeliefert, der eine lächerlich einfache Strategie für die Persistierung Ihrer Nachrichten implementiert und nur die Grundtypen int, boolean und String als Typen der Nutzdaten und Header unterstützt. Schlussfolgerungen Spring Integration selbst bietet keinen persistenten Nachrichtenkanal, der garantiert, dass Ihre Nachrichten irgendwann beim Empfänger ankommen, selbst bei einem Neustart des Systems. Wenn Sie dies jedoch weglassen, erhalten Sie eine Toolbox, die so ziemlich alles bietet, was Sie von einer vollwertigen ESB-Lösung erwarten würden, zumindest was die Unterstützung für die Implementierung von Integrationsmustern angeht. Ein JMS Message Broker könnte verwendet werden, um eine dauerhafte Nachrichtenpersistenz hinzuzufügen. Obwohl Spring Integration keine Unterstützung für persistente Nachrichtenkanäle bietet, können Sie dennoch Ihre eigenen hinzufügen. Die Implementierung eines persistenten Kanals auf der Grundlage dieser Abstraktionen erweist sich als ziemlich einfach, wenn Sie sich auf einen Datenspeicher wie Kaha verlassen. Und ein leichtgewichtiger nativer persistenter Nachrichtenkanal scheint besser in den leichtgewichtigen Ansatz von Spring Integration zu passen. In gewissem Sinne ähnelt er dem NMR in JBI-Implementierungen: Sie wissen, dass Ihre Nachrichten sicher sind, sobald sie sich darin befinden: Er mag von einem JMS Message Broker unterstützt werden, aber für den ESB-Entwickler ist er einfach eine native Komponente des Produkts.
Verfasst von

Wilfred Springer
Unsere Ideen
Weitere Blogs
Contact



