microservices – RabbitMQ messages reliability for at-least-once delivery


I wanted to ask what are the possibilities of maintaining reliability when exchanging messages between microservices, when one of those message is rejected. As of today, we don’t want to lose messages, so we are re-queueing these rejected messages. Consequently, there is a risk that the messages will be processed in a different order than expected. As a simple example, let’s take a simple architecture of two microservices A and B. A publishes two messages one after the other:

{"productStatus": "PUSBLISHED", "productId": 1}
{"productStatus": "SOLD", "productId": 1}

Microservice B rejects the first message but accepts the second. Due to the fact that we are re-queuing all rejected messages, we are processing the message with the PUBLISHED producer status again, and thus microservice B has incorrect information about the product 1 status. A simple solution that comes to mind is to add objectVersionNumber to each message so that the consumer can tell that he has processed the latest version of the object:

{"productStatus": "PUSBLISHED", "productId": 1, "objectVersionNumber": 1}
{"productStatus": "SOLD", "productId": 1, "objectVersionNumber": 2}

Are there any other approaches to solving this problem? Perhaps the semantics of the message should completely change?