К сожалению, RabbitMQ сохранит только свойства, которые перечислены на the Dead Letter Exchange page:
- очередь - имя очереди сообщение было до это было мертво-литерный,
- причина - причина DLX используется
- время - дата и время сообщения мертв литерных как 64-битного AMQP формата метки времени,
- обмена - обмен сообщение было опубликовано в
- Маршрутные ключи - ключи маршрутизации Сообщение было опубликовано с:
- count - сколько раз это сообщение было помечено в этой очереди по этой причине, и
- оригинал-expiration - первоначальное имущество истечения срока действия сообщения ,
Есть два способа решить проблему, которую вы видите, я думаю.
1) Поместите для ответа в собственном заголовке или имущественное поле, и читать его оттуда/заменить его, когда он не в обычном месте
2) Не используйте для ответа поля. Вместо этого используйте известный обмен для ответа в более поздний момент времени.
Использование поля reply-to обычно подразумевает сценарий запроса/ответа или RPC. Эти сценарии обычно требуют ответа довольно быстро. Если ответ не наступает быстро, система может, как правило, двигаться вперед без него - даже если это просто сообщение пользователю, говорящее, что «X сейчас недоступен».
Вы говорите, что используете DLX для выполнения запланированных вызовов RPC ... задержка сообщений является распространенным вариантом использования для DLX - ничего плохого в этом нет. Но отсрочка ответа RPC может столкнуться с некоторыми серьезными проблемами, выходящими за рамки того, что вы уже видите.
Например, что происходит, когда ваша система имеет икоту, а код, который сделал первоначальный запрос, больше не существует для прослушивания ответа? Ответ на это зависит от того, действительно ли вам нужен ответ для обработки. Если вам нужно, чтобы это было обработано - система столкнется с серьезными проблемами, если это не так - тогда RPC может быть опасным.
Вместо того чтобы полагаться на RPC и подразумевать временную потребность в данном ответе, часто лучше использовать двустороннюю передачу сообщений через отдельные очереди. Я написал об этом как в моем сообщении managing long running processes, так и в моем почтовом курсе/ebook RabbitMQ Patterns.
Суть его в том, что вы можете избежать необходимости в очереди ответа, поскольку исходный издатель сообщений также является подписчиком с очередью ответов.
Пример из длинного поста запущенного процесса:
var DrinkRequestSender = new Sender(/* ... details ... */);
var DrinkRequestReceiver = new Receiver(/* ... details ... */);
var DrinkStation = {
make: function(drink){
DrinkRequestReceiver.receive((response) => {
var drinkResponse = response.body;
this.trigger("drinkup", drinkResponse);
});
var drinkData = drink.toJSON();
DrinkRequestSender.send(drinkData);
}
};
В этом примере код посылает «запрос», а затем получив «ответ» - но не с помощью стандартной настройки RPC. Он использует выделенную очередь для ответа, а код на другом конце отправляет ответ обратно через обмен, который направляется в эту очередь.
Это позволяет лучше обрабатывать сценарии отказа, очень длительные процессы и многое другое.
Этот стиль двухсторонней передачи сообщений добавляет некоторые дополнительные проблемы. Во-первых, вам нужно будет построить возможность восстановления объекта, который сделал исходный запрос.
Вы можете найти это подробно в the long running process post, и есть еще немного информации в RMQ Patterns, а также (наряду с множеством других узоров).
Надеюсь, что это поможет!
Спасибо за отличный ответ Derick! Я попробую ваше предложение :) – user3791980