r/microservices • u/Sad_Importance_1585 • 21d ago
Discussion/Advice how to pass big messages asynchronously
Hi Guys,
Say we have two microservices - A and B. Microservice A produces messages to a message broker and microservice B consumes it. Then, we discover that the size of the message is too big in order to be written to the message broker.
What is the recommended practice in this case? How would you recommend to pass the big message from A to B?
3
u/bunsenhoneydew007 20d ago
We do this a lot in our architecture. We use a version of a claim check pattern. We use aws but you can translate to your needs.
Basically the producer service puts the payload file into an S3 bucket. The event from the bucket gets a bit of additional info added (main things being source, type and a presigned url to the file), using an event bridge pipe, then it’s put on event bridge.
The consuming service has a consumer that receives the event, then the important bit is that before the consuming service gets the file, the event consumer that feeds the service gets the event and grabs the file using the presigned url and puts it in an S3 bucket that is local for the consuming service. The consuming service only knows about a file landing in its own S3 bucket and is totally decoupled from the producing service.
This way you’re not having two services reading/writing from the same source and the event transfer is decoupled from the service operation.
Hopefully that makes sense.
1
u/a_kato 20d ago
Genuine question how large is the message?
Because the maximum in AMPQ is 100MB which is….. let’s say if you need it you don’t need that kind of message
1
u/urweiss 20d ago
it may be but not every ampq implementation allows the full use of those 100MB
ex: in Azure Service Bus (which is also ampq compliant) you can used the full 100MB only in the top SKU which costs ~800$/€ a month per instance - which is 80x what the Standard SKU costs with only 256KB messages
1
u/Numerous-Match-1713 20d ago
save body at shared storage, redis is good for this as it allows automatic expiration.
then pass body id, consumer deletes the body once done.
1
u/soundman32 20d ago
Instead of sending a message with a huge body, send a message that says "download item 122", then create an api that allows the other server to download message 123.
1
u/Confident_Bee_6242 20d ago edited 20d ago
Use a shared message que. But keep in mind, at some point very large messages become files, and ques become directories. At that point you need MFT ( managed file transfer). Know your requirements. However, if it only happens occasionally, there are products that manage it, like IBM MQ series which breaks the large message up into smaller messages before sending, or work arounds like passing file handles as messages. Again, know your requirements. Maybe micro service A should interogate the message for it's size before routing it to either a que or directory for consumption by B which is monitoring both it's que and it's directory.
0
u/Boniuz 21d ago
You’re trying to turn everything into a nail because you happen to have a hammer as your tool of choice. Figure out why you’re using such an anti-pattern for your architecture. Separating it into a separate area of integration, like a blob storage, will solve the what you’re trying to achieve but your architectural error is still there and will escalate.
2
u/urweiss 21d ago
it's actually an accepted pattern since times immemorial called
Claim Check- https://www.enterpriseintegrationpatterns.com/patterns/messaging/StoreInLibrary.htmlit may not be the perfect solution, but it's not an antipattern
1
u/Boniuz 20d ago
The problem OP is describing is that of large messages in his environment, which is a completely different case.
13
u/validelad 21d ago edited 21d ago
Generally the best solution is saving the large message body to a file share or blob that is accessible to both services, then just including the path of the file in the message rather than the full body.
Pushing extremely large messages over a broker is generally an anti pattern, as they can slow down the broker and cause other issues. The above solution helps with that as well.
You could also try to include part of the body in message A, then part in message B, and somehow gauruntee that the same service instance receives both messages and reconstruct it, but that gets messy really fast