2

I'm implementing RPC-style communication using RabbitMQ with the idea of creating asynchronous pipeline architecture. I'm working with Java Spring and AMQP.

I will perform a chain of RPC-style communication - a communication with one server will trigger another one, and another one will trigger another, until finally arriving at the end of the chain and the server starting the chain receiving the final answer. I have found two techniques which seem to suit my need:

  1. asyncRabbitTemplate's convertSendAndReceive(...): push using this method, once a consumer receives, trigger another convertSendAndReceive(...) and so on... a chain, until final result ends up at the server which initiated the entire process.

  2. use push/subscribe pattern, where one producer will push using convertAndSend(...), a consumer will listen via @RabbitListen and push to another which is listening and so on; in this setup, the server with the initial convertAndSend(...) call will receive the final response.

I'm not sure what is the difference between these approaches? When to go for one or the other? Is there a performance tradeoff? Is one requiring more programming effort than the other?

pewewi
  • 43
  • 3
  • I'm not sure if this is an answerable question, but just my 2 cents - a pattern of chaining messages in this fashion is likely to lead to poor results and disappointment. You need to be able to manage the workflow overall and restart failed operations. – theMayer Jan 27 '19 at 17:49

3 Answers3

2

This should have been a comment on @theMayer's answer. However, I would like to elaborate on the detail of RPC with a image. @theMayer feel free to embed this image if you would like to, then I would remove this answer.

A RPC call typically run as below: RPC implementation

Devs love ZenUML
  • 11,344
  • 8
  • 53
  • 67
  • Feel free to edit my answer. The diagram is a bit more complicated than I would have probably drawn but it’s still valid. – theMayer Jan 29 '19 at 16:09
1

I think there is a conceptual problem going on here. I don't have a sequence diagram tool handy, but in RPC,

  1. We have a consumer C and provider P
  2. C sends a message to P to invoke the service provided by P
  3. P responds directly back to C with the results asked for in C's request message

Anything other than this is NOT RPC. Other terms I've used to describe this are "request/response" and "client/server". This is the pattern used by pretty much all web services, so it is ubiquitous in application architecture.

The practice you seem to be describing here is known as event chaining. It seems simple enough in concept, but what you actually have is a series of independent actions all orchestrating themselves. It is how the real world works, and a key feature of the real world is that it is non-deterministic. That means that, given the same sequence of actions, the resulting output is not guaranteed to be the same.

Most computer programs rely upon deterministic behavior, where the same inputs always result in the exact same outputs.

theMayer
  • 15,456
  • 7
  • 58
  • 90
0

As I understand, you're building a cascade of events that should end up at the beginning. RPC pattern is intended for direct calls between two parties that know each other.

So you can definitely go with topics, if you can define how your data transforms after each station (i.e. metal_bar -> squeezed_metal_bar -> curved_metal_bar -> spoon), this will enable scaling each station independently and even adding services that monitor/react to any of the stages without changing anything else, but beware of scaling the initial caller - you might need a solution for this problem

PeterLi
  • 71
  • 5