Question

J'écris une application .NET Windows Forms qui publiera un message dans une file d'attente Websphere MQ, puis interrogera une autre file d'attente pour obtenir une réponse. Si une réponse est renvoyée, l'application traitera partiellement la réponse en temps réel. Cependant, la réponse doit rester dans la file d'attente afin qu'un travail par lots quotidien, qui se lit également dans la file d'attente des réponses, puisse effectuer le reste du traitement.

Je suis allé aussi loin que lire le message. Ce que je n'ai pas encore compris, c'est comment le lire sans le retirer.

Voici ce que j'ai jusqu'à présent. Je suis un débutant MQ, donc toutes les suggestions seront appréciées. Et n'hésitez pas à répondre 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

REMARQUE: je n'ai pas vérifié que mon code supprime réellement le message. Mais c'est comme ça que je comprends que MQ fonctionne, et cela semble être ce qui se passe. S'il vous plaît, corrigez-moi si ce n'est pas le comportement par défaut.

Était-ce utile?

La solution

Vous devez ouvrir la file d'attente avec l'option MQOO_BROWSE. Ensuite, lors de votre première lecture, vous effectuez une opération GET à l'aide de l'option MQGMO_BROWSE_FIRST. Enfin, vos GET suivants doivent utiliser l'option MQGMO_BROWSE_NEXT.

Remarque: MQOO est une option ouverte MQ et MQGMO est une option MQ Obtenir message.

Autres conseils

Vous devriez vraiment faire cela avec des files d'attente séparées. Le traitement de fin de journée doit avoir sa propre file d'attente. Une fois que vous avez traité votre partie du message, vous l'envoyez à la file d'attente EOD.

Avec l'option Parcourir, vous allez devoir garder trace des messages que vous avez déjà traités quelque part.

De plus, vous pouvez définir un délai d’attente pour l’objet GET. Vous n'avez donc pas besoin "d'attendre 1 seconde avant de vérifier la file d'attente". Comme indiqué à l’heure actuelle, vous ne pouvez pas activer la condition de non msg disponible car vous n’avez pas défini NOWAIT dans les options de réception du message.

Pour la postérité, voici une version (je pense) bien améliorée de la méthode basée sur les réponses de mamboking et 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

Je me rends compte que j'arrive un peu tard dans la discussion et que vous avez probablement déjà codé cette application. Au cas où vous auriez besoin de le modifier ou de le faire pour quelqu'un d'autre qui pourrait avoir besoin de faire quelque chose de similaire, j'ai quelques observations.

Premièrement, si vous pouvez le faire avec un client v7 QMgr et un client v7 WMQ, ce serait la solution privilégiée. Dans la v7, le support .Net a été déplacé d'un support SupportPac vers une partie du produit de base. Il y a beaucoup de nouvelles fonctionnalités, quelques corrections de bugs et de meilleures performances. En outre, sur v7, vous pouvez utiliser pub-sub ... ce qui m'amène à ma deuxième observation.

D'après la description du message d'origine, je l'aurais fait dans Pub-Sub. L'application qui met le message n'a besoin que d'en mettre un et elle n'a même pas besoin de savoir qu'elle met un sujet à l'ordre du jour. Vous pouvez en fait créer un alias sur un sujet qui le fait ressembler à une file d'attente au producteur de messages. Vos applications consommatrices peuvent ensuite vous abonner ou vous pouvez créer deux abonnements administratifs pour que les messages publiés soient dirigés vers deux files d'attente que vous désignez. Vos applications disposent alors chacune d'une file d'attente dédiée et aucune modification de code n'est impliquée pour le producteur et l'application par lots, il ne s'agit que de configuration. Bien entendu, l'application qui gère les transactions devrait consommer les messages plutôt que de les parcourir.

Les avantages sont nombreux:

  • Au fur et à mesure que la file d'attente se remplit de messages, l'indexation est vidée sur le disque et, au-dessus d'un seuil, vous constatez un impact négatif sur les performances. Par conséquent, la méthode actuelle n’a pas une très bonne échelle.
  • Avec la méthode pub-sub, vous pouvez avoir plusieurs instances des applications en temps réel ou par lots, ou les deux, et celles-ci peuvent se trouver sur le même gestionnaire QM ou sur un logiciel différent. La mise à l'échelle est facile.
  • Vous éliminez la dépendance entre les applications en temps réel et les applications batch qui doivent appartenir au même QMgr.
  • Une administration plus transparente. Si vous voyez des messages s'accumuler dans la file d'attente en temps réel, vous savez que vous avez un problème.

Quelques problèmes complètement différents ici aussi. L'une d'elles consiste à utiliser l'option Echec si mise au repos. Le but de cela est que lorsque QMgr est arrêté correctement, cette option entraîne la fin de votre appel d'API avec un code de retour indiquant que QMgr est en train de s'arrêter. Si vous n'incluez pas cette option, il est possible avec deux applications connectées ou plus que QMgr ne s'éteindra jamais et qu'il doit être forcé ou que ses processus soient tués brutalement. En règle générale, utilisez toujours Fail si Quiescing sur tous les appels d'API qui le prennent en charge. La raison pour laquelle il existe existe pour les personnes qui ont besoin de la transalité XA mais ne peuvent pas l'utiliser pour une raison quelconque. Dans ce scénario, le CONNECT et le premier appel GET ou PUT utilise Echec si la mise au repos définie et les opérations GET ou PUT suivantes ne le font pas. Cela fait que le groupe QMgr attend la fin de l’ensemble des appels GET / PUT, mais que le prochain CONNECT ou le groupe GET / PUT utilise Échec si Mise au repos afin que le groupe QMgr puisse s’arrêter si nécessaire.

L'autre observation ici est qu'il n'y a pas de Catch dans le code ici. Je suppose qu'il y en a un de plus en plus avancé dans la pile d'appels? Il est toujours conseillé d'imprimer le code de retour WMQ à partir d'une exception afin de pouvoir en rechercher la cause. Lors de missions de conseil, je signale toujours aux clients que le fait d’imprimer le code de retour (ou l’exception liée pour le code JMS / XMS) est un obstacle qui devrait empêcher la promotion d’une application en production. C'est vraiment important. Même si vous avez un piège dans le code qui appelle getMessage (), il est possible que quelqu'un réutilisant l'extrait de code donné ici ne réalise pas que cet élément important est manquant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top