Это нормально, если некоторые сообщения дублируются или утеряны?Когда JMS-клиент подключается к JMS-брокеру по сети, для любого вызова API есть три фазы.
- Вызов API, включая любые данные сообщения, передается посреднику по проводам.
- Вызов API выполняется брокером.
- Код результата и все данные сообщения передаются обратно клиенту.
Подумайте о производителе в течение минуты.Если на первом шаге соединение разорвано, то брокер так и не получил сообщение, и приложение должно было бы отправить его снова.Если на третьем шаге соединение разорвано, то сообщение было успешно отправлено, и повторная отправка приведет к дублированию сообщения.Приложение не может определить разницу между ними, поэтому единственный безопасный способ - отправить сообщение об ошибке.Если сеанс будет обработан, сообщение можно безопасно переслать во всех случаях, поскольку, если оригинал передал его посреднику, он будет откатан.
Рассмотрим потребителя.Если на третьем этапе соединение теряется, сообщение удаляется из очереди, но никогда не возвращается клиенту.Но если сеанс будет выполнен, сообщение будет доставлено при повторном подключении приложения.
Вне транзакций существует вероятность потери или дублирования сообщений.Внутри транзакции существует такое же окно неоднозначности, но оно находится на вызове COMMIT, а не на PUT или GET.В транзакционных сеансах можно отправлять или получать сообщение дважды, но не потерять его.
Спецификация JMS распознает это окно двусмысленности и предоставляет следующие рекомендации:
Еслисбой происходит в то время, когда клиент фиксирует свою работу в сеансе и возвращается метод commit, клиент не может определить, была ли транзакция зафиксирована или откатана.Такая же неоднозначность существует, когда происходит сбой между нетранзакционной отправкой сообщения PERSISTENT и возвратом из метода отправки.
Решение этой неоднозначности решает приложение JMS.В некоторых случаях это может привести к тому, что клиент будет создавать функционально дублирующиеся сообщения.
Сообщение, которое доставляется в результате восстановления сеанса, не считается дублирующим сообщением.
Сеансы JMS всегда должныбыть совершенным, за исключением случаев, когда действительно можно потерять сообщения.Если сеансы обрабатываются, то вам потребуется сеанс и соединение для каждого потока из-за модели потока JMS.
Любые рекомендации по влиянию на производительность будут зависеть от поставщика, но в целом постоянные сообщения вне точки синхронизации защищеныдиск до возврата вызова API.Но транзакционный вызов может вернуться до того, как постоянное сообщение будет записано на диск , если сообщение сохраняется до того, как COMMIT вернет .Если поставщик оптимизирует на основе этого, то гораздо эффективнее записать несколько сообщений на диск и затем зафиксировать их в пакетном режиме.Это позволяет брокеру оптимизировать операции записи и очистки диска по дисковым блокам, а не по сообщениям.Количество сообщений, помещаемых в транзакцию, уменьшается с размером сообщения и превышает определенный размер сообщения, уменьшается до единицы.
Если ваши 20k сообщений относительно малы (измеряются в k, а не в мб), тогдавы, вероятно, хотите использовать транзакции для каждого потока и настроить интервал фиксации.