Pregunta

Estoy escribiendo una aplicación .NET Windows Forms que publicará un mensaje en una cola de Websphere MQ y luego sondeará una cola diferente para obtener una respuesta. Si se devuelve una respuesta, la aplicación procesará parcialmente la respuesta en tiempo real. Pero la respuesta debe permanecer en la cola para que un trabajo por lotes diario, que también se lee en la cola de respuesta, pueda hacer el resto del procesamiento.

He llegado a leer el mensaje. Lo que no he podido entender es cómo leerlo sin eliminarlo.

Esto es lo que tengo hasta ahora. Soy un novato de MQ, por lo que cualquier sugerencia será apreciada. Y siéntase libre de responder en 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: no he verificado que mi código realmente elimine el mensaje. Pero así es como entiendo que MQ funciona, y eso parece ser lo que está sucediendo. Corrígeme si ese no es el comportamiento predeterminado.

¿Fue útil?

Solución

Necesita abrir la cola con la opción MQOO_BROWSE. Luego, en su primera lectura, realiza una OBTENCIÓN utilizando la opción MQGMO_BROWSE_FIRST. Finalmente, sus GET posteriores deben usar la opción MQGMO_BROWSE_NEXT.

Nota: MQOO es MQ opciones abiertas y MQGMO es MQ Obtener opciones de mensaje.

Otros consejos

Realmente deberías estar haciendo esto con colas separadas. El procesamiento del final del día debe tener su propia cola. Después de procesar su parte del mensaje, lo envía a la cola EOD.

Con la opción Examinar, tendrá que realizar un seguimiento de los mensajes que ya ha procesado en alguna parte.

Además, puede establecer un tiempo de espera en GET. Por lo tanto, no necesita " esperar 1 segundo antes de verificar la cola " ;. Como está escrito en este momento, no puede alcanzar la condición de no mensaje disponible porque no configuró NOWAIT en las opciones de obtención de mensaje.

Por el bien de la posteridad, aquí hay una versión (creo) mucho mejor del método basada en las respuestas de mamboking y 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

Me doy cuenta de que estoy llegando a esta discusión un poco tarde y probablemente ya hayas codificado esta aplicación. En caso de que alguna vez necesite modificarlo o para cualquier otra persona que necesite hacer algo similar, tengo un par de observaciones.

Primero, si puede hacer esto con un v7 QMgr y un cliente v7 WMQ, esta sería la solución preferida. En v7, el soporte .Net se ha movido de un SupportPac a parte del producto base. Hay una funcionalidad nueva considerable, algunas correcciones de errores y un mejor rendimiento. Además, en v7 puedes usar pub-sub ... lo que me lleva a mi segunda observación.

Según la descripción en la publicación original, lo habría hecho en Pub-Sub. La aplicación que pone el mensaje solo necesita poner uno y ni siquiera necesita saber que está poniendo un tema. En realidad, puede poner un alias sobre un tema que haga que parezca una cola para el productor del mensaje. Sus aplicaciones consumidoras pueden suscribirse o puede realizar dos suscripciones administrativas para que los mensajes publicados vayan a las dos colas que usted designe. Sus aplicaciones tienen una cola dedicada y no hay cambios de codificación para el productor y la aplicación por lotes, es solo configuración. Por supuesto, la aplicación que impulsa las transacciones necesitaría consumir los mensajes en lugar de examinarlos.

Las ventajas aquí son varias:

  • A medida que la cola se llena de mensajes, la indexación se vacía en el disco y, por encima de un umbral, verá un impacto en el rendimiento que puede ser significativo. Por lo tanto, el método actual no escala tan bien.
  • Con el método pub-sub puede tener múltiples instancias de aplicaciones en tiempo real o por lotes, o ambas, y estas pueden estar en el mismo QMgr o en uno diferente. Ampliar es fácil.
  • Elimina la dependencia entre las aplicaciones en tiempo real y por lotes que necesitan estar en el mismo QMgr.
  • Administración más transparente. Si ve mensajes que se acumulan en la cola en tiempo real, sabe que tiene un problema.

Aquí también hay un par de cuestiones completamente diferentes. Una de ellas es usar la opción Fail if Quiescing. El propósito de esto es que cuando QMgr se cierra limpiamente, esta opción hace que su llamada a la API finalice con un código de retorno que indica que QMgr se está cerrando. Si no incluye esta opción, es posible con dos o más aplicaciones conectadas que el QMgr nunca se apague limpiamente y necesite ser forzado o que sus procesos se eliminen con fuerza bruta. Como regla general, use siempre Fail if Quiescing en todas las llamadas API que lo admitan. La razón por la que existe es para las personas que necesitan transaccionalidad XA pero por alguna razón no pueden usarla. En este escenario, CONNECT y la primera llamada GET o PUT utilizan Fail si el conjunto Quiescing y las operaciones GET o PUT posteriores no lo hacen. Esto hace que QMgr espere a que se complete todo el conjunto de llamadas GET / PUT, pero luego el próximo CONNECT o GET / PUT usa Fail if Quiescing para que QMgr tenga la oportunidad de cerrarse si es necesario.

La otra observación aquí es que no hay captura en el código aquí. ¿Supongo que hay uno en alcance más arriba en la pila de llamadas? Siempre es aconsejable imprimir el código de retorno WMQ de una excepción para poder rastrear la causa raíz. En los trabajos de consultoría, siempre aconsejo a los clientes que el hecho de no imprimir el código de retorno (o la excepción vinculada para el código JMS / XMS) es una demostración que debe evitar la promoción de una aplicación a Producción. Es realmente tan importante. Incluso si tiene un problema en el código que llama a getMessage (), alguien que reutilice el fragmento de código de ejemplo aquí podría no darse cuenta de que falta esta pieza importante.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top