问题
I'm trying to write a dead letter handler service that reads messages off of a dead letter queue and then does something with the message based on the type, contents, etc.
In my C# application, I'm using EasyNetQ. I have a basic message type called MyMessage, and then a number of subtypes. EasyNetQ doesn't have a problem serializing the messages, sending them to an exchange, pulling them off the queue and then deserializing the message back into the original type.
However, if I setup the AdvancedBus in my dead letter handler to consume from the dead letter queue using MyMessage type, dead letter messages start going into the error queue instead of the dead letter queue. Apparently, the message gets changed somehow when it dead letters and can no longer be deserialized.
Is there any way to get around this?
Edit:
I may be even fundamentally misunderstanding the problem. If there's no EasyNetQ consumer on the queue, the dead letter queue works as expected, but as soon as there's a consumer, it chokes and starts putting all messages in the error queue. I even tried consuming the base IMessage type instead of my type. No difference. It still errors.
回答1:
@mountaintraveller is correct, the dead-letter messages are wrapped with extra data (like the exception), so you need to 'unwrap' them first.
Here you can find the source for HosePipe (there's no package for it): https://github.com/EasyNetQ/EasyNetQ/tree/master/Source/EasyNetQ.Hosepipe
It contains all the code you can use to
- read and publish them again
- write messages to disk
See for example this code for popping messages of the error queue: https://github.com/EasyNetQ/EasyNetQ/blob/master/Source/EasyNetQ.Hosepipe/QueueRetrieval.cs
回答2:
It turns out that EasyNetQ looks ahead at all messages on a queue before they are consumed. If one of the registered consumers is looking for a type that it won't be able to deserialize, EasyNetQ pulls it off the queue and dumps it in the error queue, rather than just letting the consumer handle the error itself.
In my case, I had a supertype "MyMessage" that the consumer was using to subscribe to the queue. Then, the producer was publishing messages of subtypes of MyMessage. The problem was that the producer and consumer were in different assemblies, and while both knew about MyMessage, only the producer knew about the subtypes. EasyNetQ wasn't able to deserialize because it didn't know the schema for the entire message. Once I included the subtypes in a reference, it started working.
Looks like Hosepipe is for reading off of the error queue, which is different, but still something I need to handle, so thanks for the references.
来源:https://stackoverflow.com/questions/42426854/how-do-i-deserialize-a-dead-lettered-message-when-dead-lettering-changes-the-typ