1

Consider there are 3 microservices - s1, s2 and s3.

s1 sends message m1.

s2 consumes message m1, applies some business logic and then sends message m2.

The problem is that s3 receives message m2 before message m1.

I tried to find a solution over internet, but I have not been able to find any proper articles or resources on this.

How to solve this problem of out-of-order messages ?

UPDATE:

  1. Martin kleppmann explained this problem statement here - youtu.be/OKHIdpOAxto?feature=shared
  2. In this video youtu.be/A8oamrHf_cQ?si=ecBkcA_k67OGgrIH at 11:30 timestamp, Martin Kleppmann mentioned "Total Order Broadcast" algorithm and also mentioned "hold back/delayed delivery" similar to what Christophe answer suggested.

Now, my doubt is does message broker(RabbitMQ) take care of this? Or developer has to handle at application level?...i am guessing Message Broker should handle these things. If its true, then do we need to configure something to make it work?

4
  • 3
    Is it possible to keep the original payload of m1 in m2? Then you wouldn’t need to consume both topics. Commented Jun 18, 2024 at 10:44
  • Not possible as messages m1 and m2 are different kind of domain events/update Commented Jun 18, 2024 at 11:00
  • 1
    how does s3 understand that there should be a m1 that is not there yet? is there a specific reference to m1 in m2? what if s1 sends multiple m1 - how does s3 know which one goes with which? Commented Jun 18, 2024 at 16:09
  • Martin kleppmann explained this problem statement here -youtu.be/OKHIdpOAxto?feature=shared Commented Jun 18, 2024 at 16:47

1 Answer 1

2

I see two solutions.

The first solution is the one suggested by jAC. The service s2 receives message m1, applies some logic, then emits a message m2 that encapsulates the message m1. The service s3 only consumes m2 messages, so there is no message ordering issue.

The second solution is "try until ready". The service s3 consumes messages m1 and m2. When the service s3 receives a message m2, it checks if it has already received the corresponding message m1. If yes, the service s3 processes the message m2. If not, it waits for one second before trying again. The corresponding message m1 should arrive in a very short time, so it is generally ok to block while waiting for it. Of course, the service s3 must consumes m1 and m2 messages independently !

Sign up to request clarification or add additional context in comments.

2 Comments

Second solution seems to be better. What will happen if m1 and m2 are not related to each other. Each time, when S3 consumes either m1 or m2 type of event, it run different kind of calculations to find result. So, if events received are out-of-order, then it impacts end result.
In this video youtu.be/A8oamrHf_cQ?si=ecBkcA_k67OGgrIH at 11:30 timestamp, Martin Kleppmann mentioned "Total Order Broadcast" algorithm and also mentioned "hold back/delayed delivery" as you suggested. Now, my doubt is does message broker(RabbitMQ) take care of this? Or develpper has to handle at application level?...i am guessing Message Broker should handle these things. If its true, then do we need to configure something to make it work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.