Как просмотреть сообщение 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 (), кто-то, повторно использующий фрагмент кода примера здесь, может не понять, что этот важный фрагмент отсутствует.