RabbitMQ - Message de commande de la livraison
J'ai besoin de choisir une nouvelle File d'attente de courtier pour mon nouveau projet.
Cette fois, j'ai besoin d'une solution évolutive de la file d'attente qui prend en charge la pub/sub, et de garder le message de commande est un must.
J'ai lu Alexis commentaire: Il écrit:
"En effet, nous pensons RabbitMQ assure une commande que Kafka"
J'ai lu le message de commande de la section de rabbitmq docs:
"Messages peuvent être retournés à la file d'attente à l'aide de AMQP méthodes que la fonction
un requeue
paramètre (de base.récupérer, de base.rejeter et de base.nack), ou en raison d'un canal
fermeture tout en maintenant des messages non reconnus...Avec la version 2.7.0 et plus tard
il est encore possible pour les consommateurs d'observer les messages de
commande si la file d'attente a plusieurs abonnés. Cela est dû à l'action de l'
d'autres abonnés qui peut requeue messages. Du point de vue de la file d'attente
les messages sont toujours détenus dans la publication de l'ordre."
Si j'ai besoin de gérer les messages selon leur ordre, je ne peux utiliser rabbitMQ avec une exclusivité de la file d'attente à chaque consommateur?
RabbitMQ est toujours considéré comme une bonne solution pour commandé message queuing?
Vous devez vous connecter pour publier un commentaire.
Eh bien, nous allons regarder de plus près le scénario que vous décrivez ci-dessus. Je pense qu'il est important de coller la documentation immédiatement avant l'extrait de code dans votre question, pour fournir le contexte:
Alors, il est clair que RabbitMQ, de 2.7.0-là, fait une plutôt drastiques amélioration par rapport à l'original AMQP spécification concernant le message de la commande.
Avec de multiples (parallèle) des consommateurs, de l'ordre de traitement ne peut pas être garanti.
Le troisième alinéa (a collé dans la question) va donner un avertissement, que je paraphrase: "si vous avez plusieurs processeurs dans la file d'attente, il n'est plus une garantie que les messages seront traitées dans l'ordre." Ils sont tous en train de dire est que RabbitMQ ne peut pas défier les lois de la mathématique.
Envisager une ligne de clients d'une banque. Cette banque, qui s'enorgueillit d'aider les clients dans l'ordre, ils sont entrés dans la banque. Les clients dans une file d'attente, et sont servis par la prochaine de 3 disponible scrutateurs.
Ce matin, il arriva donc que tous les trois scrutateurs est disponible dans le même temps, et les 3 prochains clients approché. Soudain, le premier des trois scrutateurs est devenu brutalement malade, et ne pouvait pas fini de servir le premier client de la ligne. Par le temps, ce qui s'est passé, caissier 2 en avait fini avec le client 2 et 3 guichets avait déjà commencé à servir la clientèle 3.
Maintenant, de deux choses peuvent se produire. (1) Le premier client en ligne permet de revenir à la tête de la ligne ou (2) le premier client de devancer le troisième client, à l'origine de ce comptoir d'arrêter de travailler sur le troisième client et de commencer à travailler sur le premier. Ce type de préemption de la logique n'est pas pris en charge par RabbitMQ, ni aucun autre message broker que je suis au courant. Dans les deux cas, le premier client ne prend pas vraiment en fin de compte contribué à la première de la deuxième client ne, être assez chanceux pour obtenir un bon, rapide guichets au large de la chauve-souris. La seule façon de garantir à ses clients sont aidés dans le but est d'avoir un guichet d'aider les clients un à un, ce qui va entraîner d'importants problèmes de service client pour la banque.
J'espère que cela aide à illustrer le problème que vous posez sur. Il n'est pas possible de s'assurer que les messages sont traités dans l'ordre dans tous les cas de figure, étant donné que vous disposez de plusieurs consommateurs. Il n'a pas d'importance si vous disposez de plusieurs files d'attente, plusieurs exclusive des consommateurs, des différents courtiers, etc. - il n'existe aucun moyen de garantir a priori que les messages sont traitées dans l'ordre avec plusieurs consommateurs. Mais RabbitMQ sera un best-effort.
redelivered
du message serafalse
au lieu detrue
comme un normal requeue.IBasicConsumer
(les rappels qui sont en effet appelé en même temps, d'où le fils; je n'arrive pas à croire le manuel à propos de l'ordre de traitement; les tâches peuvent se lance dans l'ordre, mais ensuite il est descendu à l'OS scheduler). Ressemble à du "pull" APIchannel.BasicGet()
est mieux comme ça. Maintenant tout que j'ai besoin de trouver l'équivalent deselect()
...Message de commande est conservé dans Kafka, mais seulement à l'intérieur de partitions plutôt que globalement. Si vos données ont besoin à la fois global de la commande et de partitions, cela rend les choses difficiles. Toutefois, si vous avez juste besoin de s'assurer que tous les événements pour le même utilisateur, etc... se retrouvent dans la même partition, de sorte qu'ils sont bien ordonné, vous pouvez le faire. Le producteur est responsable de la partition qu'ils écrivent, donc si vous êtes en mesure d'logiquement partition de vos données c'est peut-être préférable.
Je pense qu'il y a deux choses dans cette question, qui ne sont pas similaires, la consommation de l'ordre et de l'ordre de traitement.
Files d'attente de messages peut, dans une certaine mesure de vous donner une garantie que les messages vont être consommés dans l'ordre, ils ne peuvent pas, cependant, de vous donner aucune garantie sur l'ordre de leur traitement.
La principale différence ici est qu'il y a certains aspects du traitement des messages qui ne peuvent être déterminés au moment de la consommation du temps, par exemple:
Comme mentionné, le consommateur peut échouer lors de la transformation, ici le message de la consommation de l'ordre est correct, cependant, le consommateur n'a pas pu traiter correctement, ce qui va la faire revenir à la file d'attente, et jusqu'à présent, la consommation de commande est toujours intacte, mais nous ne savons pas comment l'ordre de traitement est maintenant
Si par "traitement", on entend que le message est maintenant jeté et fini complètement le traitement, puis de considérer le cas où votre temps de traitement n'est pas linéaire, en d'autres termes de traitement d'un message est plus longue que l'autre, donc si le message 3 prend plus de temps dans le traitement que prévu, les messages de 4 et 5 peut être utilisée et la fin du traitement avant de message 3 ne
Donc, même si vous avez réussi à obtenir le message d'arrière vers l'avant de la file d'attente (qui, par la manière viole la consommation de commande) vous toujours ne peut pas garantir que tous les messages avant le prochain message avez terminé le traitement.
Si vous voulez vous assurer que l'ordre de traitement alors:
Il y a des manières appropriées de guarantuee l'ordre des messages au sein de RabbitMQ abonnements.
Si vous utilisez plusieurs consommateurs, ils vont traiter le message à l'aide d'un partagées
ExecutorService
. Voir aussiConnectionFactory.setSharedExecutor(...)
. Vous pouvez définir unExecutors.newSingleThreadExecutor()
.Si vous utilisez un
Consumer
avec une seule file d'attente, vous pouvez lier cette file d'attente à l'aide de plusieurs bindingKeys (ils peuvent avoir des jokers). Les messages sont placés dans la file d'attente dans le même ordre qu'ils ont été reçus par le courtier de message.Par exemple, vous avez un seul éditeur qui publie les messages où l'ordre est important:
Maintenant, vous pourriez recevoir des messages à partir de deux sujets dans un file d'attente dans le même ordre qu'ils ont été publiés:
La
Consumer
va maintenant recevoir les messages dans l'ordre qu'ils ont été publiés, indépendamment du fait que vous avez utilisé différents sujets.Il y a quelques bons à 5 Minutes de Tutoriels dans le RabbitMQ documents qui pourraient vous être utiles:
https://www.rabbitmq.com/tutorials/tutorial-five-java.html