Как мне остановить потерю сообщений в MQ

#java #websphere #ibm-mq #mq

#java #websphere #ibm-mq #mq

Вопрос:

Я пишу Java-приложение, работающее в среде LINUX, которое выполняет транзакции в MQ с использованием SYNCPOINT. Он использует классы Websphere MQ Java для взаимодействия со службой MQ. Что я делаю в своем коде, так это следующее (псевдо):

 MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQGMO_FAIL_IF_QUIESCING | MQConstants.MQGMO_SYNCPOINT;

MQMessage message = new Message();
queue.get(message, gmo);

// process the message, save to database

databaseConnection.commit();
queueManager.commit();
  

Я в основном получаю сообщение, обрабатываю его, сохраняю в базе данных, затем вызываю фиксацию в QueueManager. Процесс прослушивает сообщение в TIBRV, чтобы выполнить корректное завершение работы.

Я тестировал процесс, чтобы убедиться, что сообщения не потеряны. Я помещаю 20 тысяч сообщений в очередь, затем запускаю процесс. Я выполняю вызов graceful shutdown в середине обработки. Затем я сравниваю количество сообщений в очереди с количеством сообщений в базе данных. Когда происходит корректное завершение работы с помощью сообщения TIBRV, количество сообщений MQ количество сообщений DB = общее количество сообщений, изначально находящихся в очереди.

Однако, когда я выполняю kill или kill -9 , я вижу, что сообщение потеряно. Я всегда получаю результат в 19999 сообщений.

Есть ли способ, которым я могу исследовать, как я теряю это сообщение? Происходит ли что-нибудь на Websphere App Server, о чем мне нужно было бы знать?

Комментарии:

1. возможно ли, что есть какая-то незавершенная транзакция, которую необходимо откатить, прежде чем вы проверите итоговые данные?

2. Из того, что я наблюдал, если я считываю сообщения из MQ, то процесс завершается без фиксации, затем, когда соединение закрывается, MQ откатывает сообщения обратно. Вы когда-нибудь видели что-то подобное?

3. Я понял, что происходит незавершенная транзакция. Websphere на самом деле не будет откатывать последнее сообщение, когда мой процесс завершится ненормально и соединение будет разорвано. То, что я делаю сейчас, это открываю очередь для просмотра, и я извлекаю сообщение в конце моей транзакции.

Ответ №1:

Нет причин ожидать согласования чисел при использовании однофазной фиксации. Программа всегда будет находиться между вызовами WMQ и DB Commit или между вызовами DB и WMQ Commit, когда вы ее завершите.

То, о чем вы просите, потребует двухфазной (XA) фиксации. Для WMQ 2PC потребуется, чтобы приложение использовало режим привязок, а WMQ был координатором ресурсов. Затем вы должны вызвать MQBEGIN, выполнить обновления WMQ и базы данных, а затем вызвать MQCOMMIT. Таким образом, транзакции WMQ и DB будут успешными или завершатся неудачей одновременно.

Комментарии:

1. В значительной степени то, что я бы сказал, за исключением того, что это был бы поставщик транзакций.

2. Мы рассмотрели двухфазную фиксацию. К сожалению, руководство не согласилось на его использование. Они сочли изменения слишком трудоемкими. Мы пришли к выводу, что лучшей альтернативой является фиксация сначала в DB, а затем в MQ. Лучше иметь сообщение, обманутое, чем потерять сообщение полностью.

Ответ №2:

Вы подключаетесь к MQ в режиме привязок или в режиме клиента? По моему опыту, транзакции не работали «из коробки» в режиме клиента, но они работали в режиме привязок.

Комментарии:

1. Я подключаюсь, используя TRANSPORT_MQSERIES в качестве моего соединения и используя MQGMO_SYNCPOINT в моих параметрах получения. Если я подключусь в режиме привязок, как это повлияет на рабочий процесс моего кода, описанный выше? Будет ли Wepshere автоматически откатывать последнюю транзакцию при потере соединения?

2. Использование TRANSPORT_MQSERIES означает, что вы могли бы подключаться либо через привязки, либо через клиент, в зависимости от того, установили ли вы имя хоста. Источник: publib.boulder.ibm.com/infocenter/wmqv7/v7r0m0/index.jsp?topic =/… Вы установили имя хоста? Запущен ли диспетчер очередей на том же хосте, что и WebSphere App Server, или на другом хосте?