8. ledna 2013

Dead Letter Channel nebo Invalid Message Channel? Toť otázka

Řešil jsem teď zajímavou filozofickou otázku. Potřeboval jsem v rámci integrace někam odkládat JMS zprávy, které se nepodařilo aplikačně zpracovat. Rozhodl jsem se je odkládat do speciální fronty, kterou jsem nazval Dead Letter Queue. Což je termín, který se používá na platformě WebSphere MQ. Naopak moje platforma je SOA Suite, která žádný podobný termín nemá (a řekl bych, že nejen termín, ale ani koncept).

Své řešení jsem hrdě (a úspěšně) představil v týmu a argumentačně ho podpořil tvrzením, že jde o vzor z Enterprise Integration Patterns (EIP). Tyto patterny jsou shrnuty v knížce, kterou vřele doporučuji - zcela jednoznačně jde o bibli messagingu.

Už je to nějaký čas, co jsem knížku četl a jelikož jsem si matně pamatoval, že ve skutečnosti jsou tam dva takové podobné vzory, znovu jsem si dané kapitoly pročetl. Co kdyby se vynořila nějaká zvídavá otázka :-) Po (znovu)přečtení jsem uvažoval, kterému vzoru se moje řešení více podobá - Dead Letter Channel nebo Invalid Message Channel? Ještě než se k těmto vzorům dostanu, předestřu, jak vypadá moje řešení.


Aniž bych zabíhal do přílišných podrobností. JMS listener vyčte zprávu z JMS fronty Input Queue a pošle ji ke zpracování do orchestrační/business logiky. Zde proběhnou validace zprávy, plus nějaká omáčka a pak jsou v rámci orchestrace volaný 3-4 externí služby (z diagramu vypuštěno). Pokud je během orchestrace vyhozena SOAP fault, zapíše se iniciální zpráva do JMS fronty Dead Letter Queue. Zároveň se do hlavičky zprávy přidá "uživatelská hlavičková vlastnost" (custom header property), kam se zapíše, ze které fronty byla zpráva původně vyčtena.

Nyní k oběma vzorům. První odstavec je definice vzoru a následuje signifikantní text, který jsem si podtrhl na  Kindlu. A obrázek :-)

Dead Letter Channel


"When a messaging system determines that it cannot or should not deliver a message, it may elect to move the message to a Dead Letter Channel."

"Typically, each machine the messaging system is installed on has its own local Dead Letter Channel so that whatever machine a message dies on, it can be moved from one local queue to another without any networking uncertainties. ... When the messaging system moves the message, it may also record the original channel on which the message was supposed to be delivered."

"Determining if a message should be moved to the Dead Letter Channel is an evaluation of the messages's header performed by the messaging system."

Vzor Dead Letter Channel (zdroj EIP)

Invalid Message Channel

"The receiver should move the improper message to an Invalid Message Channel, a special channel for messages that could not be processed by their receivers."

"An Invalid Message Channel is like an error log for messaging. When Something goes wrong in an application, it's a good idea to log the error. When something goes wrong processing a message, it's a good idea to put the message on the channel for invalid messages."

"If an error occurs while processing the message, the message is invalid and should be moved to the Invalid Message Channel. If it occurs while the application processes the data from the message, that is an application error that has nothing to do with messaging."

Vzor Invalid Message Channel (zdroj EIP)

Co to teda je?

Moje řešení má znaky obou výše uvedených vzorů, ale zároveň se jim i vymyká. Což není nic divného - moje platforma není messagingová, JMS fronty používá pouze jako rozhraní kvůli decouplingu.

Co si o tom myslíte vy? Jak byste nazvali takovou "odkládací" frontu? Nebo existuje nějaký vzor, který toto řešení/problém pokrývá lépe? Budu rád, když se v diskuzi podělíte.

Související články

2 komentáře:

  1. Ahoj,

    nějakou dobu čtu tvůj blog,a vždy se těším na nové články, jen tak dál :).

    Další dva návrhy :

    1. použit Fault policy a ora-human-intervention - Což bude mít za následek uloženi payloadu do dehydration store. Později může uživatel v EM tyto data vidět a připadne ne/upravit a znovu poslat.
    Výhoda: vše je hotovo od oracle a je zapotřebí naproste minimum změn v tvé composite app. Cluster není problém :).
    Nevýhoda: papa to DB (soa db:) a jak už z nazvu ora-human-intervention vyplývá je zapotřebí tu a tam člověka (což není sice úplně přesně, but..) ke znovu zpracování.

    2. nastaveni topiku kdy je zprava smazaná, až je opravdu zpracována - Acknowledge policy.
    Přiznám se že jsem ještě neměl tu čest se do teto problematiky ponořit.
    Zde jak se říká "vařím z vody" :D


    Flame Master

    OdpovědětVymazat
    Odpovědi
    1. Díky, budu se snažit. A díky za názor.

      Ad 1) Když se budeme bavit o konkrétní platformě (SOA Suite), tak politika + ora-human-intervention je dobré řešení. Ale v mém případě by to fungovalo už out-of-the-box: když je vstupem JMS fronta a vyhodím z kompozitní aplikace fault, tak přesně k tomuhle dojde (i bez politiky).

      Problém je, že instance kompozitky zůstane ve stavu running (stejně jako v případě použití politiky), což jsme nechtěli. Takže jsem odroloval transakci v BPELu, zapsal do DLQ a kompozitku exitnul.

      Ad 2) Tohle je taky zajímavý nápad, ale nevím, jestli by to fungovalo (taky vařím z vody). Jednak je otázka, jak má JMS adapter nastavený acknowledge mode (docela bych řekl, že transakčně) a jestli to jde v SOA Suite nějak nastavit (tipnul bych si, že ne).

      Pokud by to náhodou šlo, tak nevím přesně, jak by to fungovalo - v dokumentaci se píše, že Messages that have been received but not acknowledged may be redelivered. Neblokovalo by to pak ostatní zprávy ve frontě?

      Vymazat