3
votes

Consommateur JMS bloquant d'autres groupes JMSX

J'essaie de déterminer si je peux de toute façon avoir un impact sur l'ordre de traitement des messages du consommateur lorsqu'un message est remis dans la file d'attente. J'ai un code simple ci-dessous qui m'aide à reproduire le problème. Je pousse simplement des messages dans une file d'attente avec différents JMSXGroupIds dans un certain ordre:

  1. "A1" (JMSXGroupId: 1)
  2. "B1" (JMSXGroupId: 2)
  3. "A2" (JMSXGroupId: 1)
  4. "C1" (JMSXGroupId: 3)
  5. "B2" (JMSXGroupId: 2)

Le code effectue un rollback A1 (il réessaye initialement le message 3 fois) et il retourne dans la file d'attente avec un délai. Cependant, le consommateur attend ensuite de pouvoir reprendre A1 (après avoir attendu le laps de temps différé), ce qui signifie que les groupes B1 et C1 sont bloqués derrière A1 et ne sont jamais traités.

Idéalement, ce que j'espérais est que lorsque A1 est remis dans la file d'attente et dit d'attendre, le consommateur prendrait B1 et C1 ... ce que j'essaie finalement de faire est d'empêcher un JMSXGroup de bloquer les autres sur un consommateur. En outre, cela vaut probablement la peine d'ajouter que je dois conserver l'ordre de séquence des messages pour A (A1, A2, A3 ...) et que j'espérais le faire en les laissant dans la file d'attente, plutôt que d'avoir à construire une solution de gestion pour les exceptions.

onException(Exception.class)
            .log("Exception Caught !! ")
            .redeliveryDelay("1000")
            .maximumRedeliveries(3)
            .handled(false)
            .markRollbackOnly()
            .log("log:output");

    from("amq:queue:mailbox?concurrentConsumers=1")
            .to(logEndpoint)
            .process(exchange -> {
                if(exchange.getIn().getBody(String.class).contains("A")) {
                    throw new Exception("Found A");
                }
            });

J'utilise un micro-service Apache Camel basé sur Java avec des routes traitées. Rien d'extraordinaire mais je peux fournir plus de détails / détails de configuration si nécessaire.

Merci d'avance


1 commentaires

Salut - J'espère que Camel et / ou ActiveMQ peuvent me fournir des messages de blocage pour un seul JMSXGroupId, et j'espère aussi le faire en les laissant dans la file d'attente, plutôt que d'avoir à construire une gestion solution pour les exceptions. " Vous vous demandez si vous avez compris cela? Avoir un consommateur pour chaque JMSXGroupId ne s'adapte pas à ce que j'espérais faire: Grouper par un UID utilisateur. tnx pour tout conseil


3 Réponses :


2
votes

Un ordre strict sur une file d'attente est lié à des problèmes comme celui-ci car la file d'attente doit adhérer à sa sémantique fondamentale premier entré premier sorti (c'est-à-dire FIFO). Même si B1 a été ramassé immédiatement après l'échec d'A1, vous devrez attendre pour consommer A2 jusqu'à ce que A1 soit consommé afin de préserver l'ordre, et puisque la file d'attente doit être consommée, FIFO qui bloquerait la consommation de C1 et de l'un des autres messages derrière.


0 commentaires

1
votes

Vous utilisez la redistribution de Camel qui ne fera que la redistribution en appelant la méthode du processeur (par exemple là où elle a échoué) et non la route entière.

Vous pouvez envisager d'utiliser les transactions JMS et laisser le message revenir jusqu'au courtier JMS et configurer les paramètres de redistribution sur le courtier de messages.

Si vous avez une copie du livre Camel in Action, je vous suggère de lire le chapitre sur les transactions et le chapitre sur la gestion des erreurs.


0 commentaires

1
votes

Votre problème est dû au concurrentConsumers = 1 sur le point de terminaison consommateur. Si vous n'avez qu'un seul consommateur, il est impossible de traiter les groupes JMS en parallèle .

Avec cette limitation, vous avez effectivement un consommateur exclusif et le JMS l'en-tête de groupe n'a aucun effet car il n'y a qu'un seul consommateur pour traiter les messages de toute façon.

L'en-tête JMSXGroupId garantit que tous les messages avec le même ID de groupe sont traités par le même consommateur . Donc, si vous aviez 3 consommateurs, les 3 groupes de votre exemple pourraient être traités en parallèle même si le message A1 "bloque" le consommateur du groupe A pendant un certain temps.

Cependant, lorsque vous avez moins de consommateurs que de groupes , il est bien entendu qu'un message peut bloquer d'autres groupes, simplement parce qu'un consommateur gère plusieurs groupes.


1 commentaires

Salut burki, j'aurais dû dire que j'avais simplifié ma solution pour ce post mais que j'avais fonctionné avec 2 consommateurs et 6 groupes (A, B, C, D, E, F - tous avec trois messages - A1, A2, A3 , etc.) et j'ai toujours vu le même problème, qui correspond à votre dernière phrase.