Как просмотреть сообщение Websphere MQ, не удаляя его?
Я пишу приложение .NET Windows Forms, которое отправит сообщение в очередь Websphere MQ, а затем опросит другую очередь для ответа. Если ответ будет возвращен, приложение частично обработает ответ в режиме реального времени. Но ответ должен оставаться в очереди, чтобы ежедневное пакетное задание, которое также считывает из очереди ответов, могло выполнить остальную часть обработки.
Я дошел до чтения сообщения. Что я не смог выяснить как читать его, не удаляя.
вот что у меня есть до сих пор. Я новичок MQ,поэтому любые предложения будут оценены. И не стесняйтесь отвечать на C#.
Public Function GetMessage(ByVal msgID As String) As MQMessage
Dim q = ConnectToResponseQueue()
Dim msg As New MQMessage()
Dim getOpts As New MQGetMessageOptions()
Dim runThru = Now.AddMilliseconds(CInt(ConfigurationManager.AppSettings("responseTimeoutMS")))
System.Threading.Thread.Sleep(1000) 'Wait for one second before checking for the first response'
While True
Try
q.Get(msg, getOpts)
Return msg
Catch ex As MQException When ex.Reason = MQC.MQRC_NO_MSG_AVAILABLE
If Now > runThru Then Throw ex
System.Threading.Thread.Sleep(3000)
Finally
q.Close()
End Try
End While
Return Nothing 'Should never reach here'
End Function
Примечание: Я не проверил, что мой код действительно удаляет сообщение. Но именно так я понимаю, что MQ работает, и это, похоже, происходит. Пожалуйста, поправьте меня, если это не поведение по умолчанию.
4 ответов
вам нужно открыть очередь с опцией MQOO_BROWSE. Затем при первом чтении вы делаете GET, используя опцию MQGMO_BROWSE_FIRST. Наконец, ваши последующие GET должны использовать опцию MQGMO_BROWSE_NEXT.
Примечание: MQOO-это MQ open options, а MQGMO-MQ Get Message Options.
вы действительно должны делать это с отдельной очереди. В конце дня обработка должна иметь свою очередь. После обработки вашей части сообщения вы отправляете его в очередь EOD.
с опцией обзора вам придется отслеживать, какие сообщения вы уже обработали где-то.
кроме того, вы можете установить тайм-аут ожидания на GET. Таким образом, вам не нужно "ждать 1 сек перед проверкой очереди". Как написано прямо сейчас, вы не можете нажать no msg available условие, потому что вы не установили NOWAIT в параметрах получить сообщение.
для потомства, вот (я думаю) значительно улучшенная версия метода, основанного на mamboking и ответах jmucchiello.
Public Function GetMessage(ByVal correlID As Byte()) As MQMessage
Dim waitInterval = CInt(ConfigurationManager.AppSettings("responseTimeoutMS"))
Dim q As MQQueue = Nothing
Try
Dim msg As New MQMessage()
Dim getOpts As New MQGetMessageOptions()
q = ConnectToResponseQueue()
msg.MessageId = MQC.MQMI_NONE
msg.CorrelationId = correlID
getOpts.MatchOptions = MQC.MQMO_MATCH_CORREL_ID
getOpts.WaitInterval = waitInterval
getOpts.Options = MQC.MQGMO_BROWSE_FIRST Or MQC.MQGMO_WAIT
q.Get(msg, getOpts)
Return msg
Finally
If q IsNot Nothing AndAlso q.IsOpen() Then q.Close()
End Try
End Function
Я понимаю, что я прихожу к этому обсуждению немного поздно, и вы, вероятно, уже закодировали это приложение. В случае, если вам когда-либо понадобится изменить его или для кого-то еще, кому может понадобиться сделать что-то подобное, у меня есть пара замечаний.
во-первых, если вы можете сделать это с помощью V7 QMgr и клиента WMQ v7, это будет предпочтительным решением. В v7 поддержка .Net была перемещена из SupportPac в часть базового продукта. Есть значительный новый функционал, некоторые баги исправления и повышение производительности. Кроме того, на v7 вы можете использовать pub-sub...что подводит меня ко второму замечанию.
основываясь на описании в исходном посте, я бы сделал это в Pub-Sub. Приложение, которое помещает сообщение, нужно только поставить один, и ему даже не нужно знать, что он ставит тему. Вы можете поместить псевдоним над темой, которая будет выглядеть как очередь к производителю сообщений. Ваши потребляющие приложения могут подписаться, или вы можете сделать два административные подписки, чтобы опубликованные сообщения шли в две назначенные очереди. Ваши приложения затем имеют выделенную очередь и никаких изменений кодирования не участвуют для производителя и пакетного приложения, это просто конфигурация. Конечно, приложение, управляющее транзакциями, должно будет фактически потреблять сообщения, а не просматривать их.
плюсов здесь несколько:
- когда очередь заполняется сообщениями, индексирование сбрасывается на диск и выше порога вы увидите хит производительности, который может быть значительным. Поэтому текущий метод не так хорошо масштабируется.
- С помощью метода pub-sub вы можете иметь несколько экземпляров приложений в реальном времени или пакетных приложений или обоих, и они могут быть на одном или другом QMgr. Масштабирование легко.
- вы устраняете зависимость между приложениями реального времени и пакетами, которые должны быть на одном QMgr.
- более прозрачное управление. Если вы видите создание сообщений в очереди реального времени вы знаете, что у вас есть проблема.
несколько совершенно разных вопросов здесь, а также. Одним из них является использование не если вариант "замораживания". Цель этого заключается в том, что когда QMgr выключается чисто, этот параметр заставляет ваш вызов API заканчиваться кодом возврата, указывающим, что qmgr завершает работу. Если вы не включаете эту опцию, то это возможно с двумя или более подключенными приложениями, которые QMgr будет никогда выключите чисто и нужно быть принужденным вниз или иметь свои процессы убить с грубой силой. Как правило, всегда используйте не если приостановка на все вызовы API, которые поддерживают его. Причина, по которой он вообще существует, - это люди, которым нужна транзакция XA, но по какой-то причине они не могут ее использовать. В этом случае подключение и первый вызов GET или PUT использует сбой, если Quiescing set и последующие операции GET или PUT не. Это заставляет QMgr ждать весь набор вызовов GET/PUT для завершите, но затем следующее соединение или GET / PUT использует сбой, если Quiescing, поэтому QMgr имеет шанс закрыть при необходимости.
другое наблюдение здесь заключается в том, что в коде здесь нет подвоха. Я предполагаю, что есть один в области дальше по стеку вызовов? Всегда рекомендуется распечатать код возврата WMQ из исключения, чтобы можно было отследить первопричину. При консультациях я всегда советую клиентам, что не удалось распечатать код возврата (или связанное исключение для кода JMS/XMS) - это showstopper, который должен предотвратить продвижение приложения в производство. Это действительно так важно. Даже если у вас есть уловка в коде, который вызывает getMessage (), кто-то, повторно использующий фрагмент кода примера здесь, может не понять, что этот важный фрагмент отсутствует.