Pergunta

Eu estou escrevendo um aplicativo de formulários .NET Windows que irá postar uma mensagem para uma fila de Websphere MQ e depois consultar uma fila diferente para uma resposta. Se a resposta é retornada, o aplicativo será parcialmente processar a resposta em tempo real. Mas as necessidades de resposta para ficar na fila para que um trabalho em lotes diário, que também lê a fila de resposta, pode fazer o resto do processamento.

Eu comecei na medida em que a leitura da mensagem. O que eu não tenho sido capaz de descobrir é como a lê-lo sem removê-lo.

Aqui está o que eu tenho até agora. Eu sou um novato MQ, por isso todas as sugestões serão apreciadas. E sinta-se livre para responder em 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

NOTA: Eu não tenho verificado que o meu código realmente remove a mensagem. Mas é assim que eu entendo MQ para o trabalho, e que parece ser o que está acontecendo. Por favor, corrija-me se isso não é o comportamento padrão.

Foi útil?

Solução

Você precisa abrir a fila com a opção MQOO_BROWSE. Em seguida, na sua primeira leitura que você faz um GET usando a opção MQGMO_BROWSE_FIRST. Finalmente, seus s Get subseqüentes deve usar a opção MQGMO_BROWSE_NEXT.

Nota: MQOO é MQ opções abertas e MQGMO é MQ Obter Opções de Mensagens

.

Outras dicas

Você realmente deveria estar fazendo isso com filas separadas. O Fim do processamento Dia deve ter sua própria fila. Depois de efectuar a sua parte da mensagem, você enviá-lo para a fila EOD.

Com a opção Browse você vai ter que manter o controle de algum lugar que as mensagens que você já processado.

Além disso, você pode definir um tempo limite de espera na GET. Então você não precisa "esperar 1 segundo antes de verificar fila". Como escrito agora você não pode bater a condição não msg disponível porque você fez NOWAIT não set nas opções de mensagens get.

Para bem da posteridade, aqui está um (eu acho) versão muito melhorada do método baseado em mamboking e respostas de 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

Eu percebo que estou vindo para esta discussão um pouco tarde e você provavelmente já codificado este aplicativo para cima. No caso de precisar modificá-lo ou para qualquer pessoa que pode precisar fazer algo semelhante, eu tenho um par de observações.

Em primeiro lugar, se você pode fazer isso com um v7 QMgr e um cliente v7 WMQ esta seria a solução preferida. Em v7, o suporte Net foi movido de um SupportPac a uma parte do produto base. Há uma considerável nova funcionalidade, algumas correções de bugs e melhor desempenho. Além disso, em v7 você pode usar pub-sub ... o que me leva ao meu segundo observação.

Com base na descrição no post original, eu teria feito isso no Pub-Sub. O aplicativo que coloca as necessidades de mensagens só colocar um e não precisa nem sabe que está colocando a um tópico. Você pode realmente colocar um alias sobre um tema que faz com que pareça uma fila para o produtor mensagem. Seus aplicativos que consomem pode então se inscrever ou você pode fazer duas assinaturas administrativas para que as mensagens publicadas ir para duas filas que você designar. Seus aplicativos, em seguida, cada um tem uma fila dedicada e sem alterações de codificação estão envolvidos para o produtor eo app lote, é apenas de configuração. É claro que o aplicativo condução das operações seria necessário a consumir efectivamente as mensagens em vez de procurá-los.

As vantagens aqui são várias:

  • Como a fila enche de mensagens, indexação fica descarregado para o disco e, acima de um limiar você verá um acerto de desempenho que pode ser significativo. Portanto, o método atual não escala muito bem.
  • Com o método pub-sub pode ter várias instâncias, quer do tempo real ou aplicativos em lote ou ambos, e estes podem estar na mesma ou diferente QMgr. Scaling up é fácil.
  • Você eliminar a dependência entre o tempo real e aplicativos em lote que precisam estar na mesma QMgr.
  • administração mais transparente. Se você ver mensagens de edificação na fila em tempo real você sabe que tem um problema.

Um par de questões completamente diferentes aqui também. Uma delas é usar a opção falhar se Efetuando Quiesce. O objetivo deste é que quando o QMgr é desligado corretamente esta opção faz com que sua chamada de API para terminar com um código de retorno que indica o QMgr está sendo desligado. Se você não incluir essa opção, então é possível com dois ou mais conectados aplicativos que o QMgr irá não desligado corretamente e precisam de ser forçado para baixo ou ter seus processos mortos com força bruta. Como regra geral, use sempre falhar se Efetuando Quiesce em todas as chamadas de API que o suportam. A razão é que existe é para pessoas que precisam XA transacionalidade mas por algum motivo não pode usá-lo. Neste cenário, o CONNECT e os primeiros GET ou chamada PUT usos falhar se definir Efetuando Quiesce e subsequentes operações de obter ou colocar não. Isso faz com que o QMgr que esperar por todo o conjunto de GET / chamadas posto a completa, mas, em seguida, a próxima CONNECT ou GET / PUT utiliza falhar se Efetuando Quiesce para que o QMgr tem a chance de encerrar, se necessário.

A outra observação aqui é que não há capturas no código aqui. Eu estou supondo que há um em âmbito mais acima na pilha de chamadas? É sempre aconselhável para imprimir o código WMQ retorno de uma exceção para que você possa rastrear a causa raiz. Em trabalhos de consultoria Eu sempre aconselhar os clientes que a incapacidade de imprimir o código de retorno (ou a exceção ligado para o código JMS / XMS) é um showstopper que devem evitar a promoção de um aplicativo para Produção. É realmente muito importante. Mesmo se você tiver um prendedor no código que chama getMessage (), alguém reutilizar o código de exemplo de trecho aqui pode não perceber esta peça importante está faltando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top