[rabbitmq-discuss] Orchestration vs. Choreography
Isaias Barroso
isaias.barroso at gmail.com
Sun Jan 8 14:52:34 GMT 2012
Hi Ciprian,
I've seen that Spring Integration with AMQP module can be a solution for
Orchestration, I'll do a deep analysis on it. But I think is more restrict
that mixed approach (b)
Best regards
On Sun, Jan 8, 2012 at 12:46 PM, Isaias Barroso <isaias.barroso at gmail.com>wrote:
> Hi Ciprian,
>
>
> I've also pondered about the same topic a while ago... (Though I
>> haven't tried it in practice.) As such my options were the following:
>>
>> a) (the easiest one) Go with the choreography approach, but
>> instead of naming the queue of the next service (and send to a direct
>> exchange), just send it to an exchange named by the next step's
>> purpose (like "enrich", "validate", etc.). Maybe make this a topic
>> exchange and put enough information in the routing key to allow
>> "debugging" by being able to register another queue and "capture" the
>> traffic.
>>
>>
> Yes, I agree with you, send to a exchange is more apropriate
>
>
>> b) (the "declarative" approach) Why not have the orchestration
>> approach (in a declarative flavor) combined with choreography:
>> * let's assume that you have a task which goes through a set of
>> processes (transformations or just validations, etc.) which can be
>> described as decision tree (a binary tree of actions, where each node
>> is a process and the two children (one for success and one for
>> failure) are the next process to be executed);
>> * now you just put this decision tree inside the "envelope" of
>> each message, send it to the root process;
>> * this process executes its logic and based on the outcome
>> (success or failure), extracts one of it's subtrees, puts that in the
>> new envelope and together with the new message sends it to the root of
>> the new tree; (evidently at some point the new tree would be empty,
>> which means it should stop sending it further;)
>> * (you could again use "purpose" names for exchanges instead of
>> direct queues;)
>> * you could extend this to a graph (maybe containing cycles, thus
>> obtaining loops), by saying that each node has two links to other
>> nodes;
>> * of course yet another extension would be to allow "labeled" node
>> links, i.e. each process outputs two things: a next-step string label,
>> and the new message, and now you select from the labeled links the one
>> matching the label; (maybe have something as a default link);
>>
>> Thus with option b) you obtain both the advantages of choreography
>> (i.e. no middle man to become a single point of failure or
>> bottleneck), but also the advantages of orchestration (i.e. each
>> message having it's own "route" through the processes). At the same
>> time you keep the processors "dumb", none knowing of another.
>>
>
> Very interesting this approach, and better the possibility to eliminate a
> possible SPOF.
>
>
>
>>
>> Hope this helps.
>> Ciprian.
>>
>> P.S.: If you like this approach (b), you could go even further and
>> instead of using a static decision tree (or graph) you could
>> substitute that with an embedded language or machine which allows
>> generic operations on both the old and new message to decide the next
>> actions. (I could expand on this if someone is interested.)
>>
>> I think that (b) approach can be more flexible for large and complex
> process and it sounds good.
>
> Maybe this topic can generate good discussions and patterns for complex
> process management.
>
> Best regards
>
>
>
>
>> A practical (not very elegant) Java approach:
>> * define a Java interface with a method like `public AmqpTarget
>> decide (MyMessage old, MyMessage new)` (or something similar), where
>> `AmqpTarget` has two fields for exchange and routing key;
>> a) if all the processes share the same code and are upgraded at
>> the same time, just instantiate a serializable object implementing
>> that interface and put that in the envelope instead of the decision
>> tree;
>> b) if you don't have shared code or you want to keep your options
>> opened:
>> * for each different "workflow" define a new public "top" class
>> (i.e. not nested or anonymous) implementing that interface with as few
>> dependencies as possible;
>> * in the envelope instead of the decision tree put the byte-code
>> of this class (you can use the
>>
>> `MyWorkflowClass.class.getResourceStream(MyWorkflowClass.class.getCanonicalName())`
>> and the canonical name; (be careful to use caching or you'll get
>> `PermGenError` or similar;)
>> * to instantiate the class on the receiver just create a custom
>> classloader which when asked for the bytecode of that known class just
>> returns the bytes previously stored;
>>
>
>
>
> --
> Isaías Barroso
>
>
--
Isaías Barroso
Consultor SAP NetWeaver / Oracle (SOA / ADF) / JEE
Belo Horizonte - MG
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20120108/0b70a406/attachment.htm>
More information about the rabbitmq-discuss
mailing list