Что произойдет, если издатель завершит работу до получения подтверждения?
Я хочу убедиться, что определенные типы сообщений не могут быть потеряны, поэтому я должен использовать Confirms (также известное как Publisher Acknowledgements).
Посредник теряет постоянные сообщения, если он падает до того, как указанные сообщения будут записаны на диск. При определенных условиях это заставляет брокера вести себя удивительным образом.
Например, рассмотрим этот сценарий:
- клиент публикует постоянное сообщение в долговременную очередь
- клиент получает сообщение из очереди (отмечая, что сообщение является постоянным, а очередь надежным), но еще не подтвердило его,
- брокер умирает и перезапускается, и
- клиент переподключается и начинает потреблять сообщения.
В этот момент клиент может разумно предположить, что сообщение будет доставлено снова. Это не так: перезапуск привел к тому, что брокер потерял сообщение. Чтобы гарантировать постоянство, клиент должен использовать подтверждения.
Но что делать, если с помощью подтверждения издатель отключается до получения подтверждения, и сообщение по какой-то причине не было доставлено в очередь (например, сбой сети).
Предположим, у нас есть простая конечная точка REST, где мы можем ПОСТАВИТЬ новые КОММЕНТАРИИ, и, когда создается новый КОММЕНТАРИЙ, мы хотим опубликовать сообщение в очереди. (Примечание: не имеет значения, отправляю ли я сообщение нового комментария, который в конце не создается, например, из-за отката).
CommentEndpoint {
Channel channel;
post(String comment) {
channel.publish("comments-queue",comment) // is a persistent queue
Comment aNewComment = new Comment(comment)
repository.save(comment)
// what happens if the server where this publisher is running terminates here ?
channel.waitConfirmations()
}
}
Когда сервер перезагружается, канал исчезает, и сообщение не может быть доставлено. Одно решение, которое мне приходит в голову, состоит в том, что после перезапуска запросите последние комментарии (например, комментарии, созданные за последние 3 минуты до сбоя?) В хранилище и отправьте по одному сообщению для каждого и ожидайте подтверждения.
1 ответ
То, что вас беспокоит, больше не проблема RabbitMQ, это проблема распределенных транзакций. Это обсуждение дает одно разумное облегченное решение. И существуют более строгие решения, например, двухфазное принятие, трехфазное принятие и т. Д., Чтобы обеспечить согласованность данных, когда это действительно необходимо.