2017-01-19 3 views
0

Je suis nouveau sur NServiceBus mais je l'utilise actuellement avec SQL Server Transport pour envoyer des messages entre trois machines: l'une appartient à un noeud final appelé Server et deux appartiennent à un noeud final appelé Agent. Cela fonctionne comme prévu, avec les messages envoyés au point de terminaison Agent distribué à l'une des deux machines via le round-robin par défaut.Rediriger le message NServiceBus basé sur la disponibilité Endpoint

Je souhaite maintenant ajouter un nouveau point de terminaison appelé PriorityAgent avec une file d'attente différente et deux machines supplémentaires. Bien que tous les points de terminaison utilisent le même type de message, je sais où chaque message doit être traité avant de l'envoyer, donc normalement je peux simplement choisir le bon point de destination et le message sera traité en conséquence.

Cependant, je dois construire dans un cas particulier: si toutes les machines sur le point de terminaison PriorityAgent sont actuellement bas, les messages qui doivent normalement être envoyés devraient y être envoyés à l'extrémité Agent à la place, afin qu'ils puissent être traités sans délai. D'autre part, si toutes les machines sur le point de terminaison Agent sont actuellement en panne, tous les messages Agent ne doivent pas être envoyés à PriorityAgent, ils peuvent simplement attendre le retour d'une machine Agent.

J'ai recherché la bonne manière de mettre en œuvre ceci, et n'ai pas vu beaucoup de résultats. J'imagine que ce n'est pas un scénario inédit, donc mon hypothèse est que je cherche les mauvaises choses ou que je pense à ce problème de la mauvaise façon. Pourtant, je suis venu avec quelques solutions possibles:

  1. piste séparément les battements de coeur de PriorityAgent machines et ajouter un mutator ou le comportement de changer la destination des messages sortants PriorityAgent au point d'extrémité Agent si ces battements de cœur arrêtent.

  2. Donnez PriorityAgent messages à une courte expiration, et en quelque sorte gérer l'expiration de rediriger les messages vers le point de terminaison Agent. Je ne suis pas sûr que ce soit réellement possible.

L'une de ces solutions est-elle sur la bonne voie, ou suis-je entièrement hors-base?

Répondre

1

Vous n'avez pas vu beaucoup faire cela parce que c'est considéré comme un anti-modèle. Ou plutôt l'un des deux antipatterns.

1) Soit vous envoyez une commande, auquel cas le RECEIVER de la commande définit le contrat. Pourquoi envoyez-vous une commande définie par PriorityAgent à Agent? Il ne devrait pas y avoir de couplage là-bas. Une commande appartient à UN point de terminaison/file d'attente logique.

2) Ou vous publiez un événement défini par celui qui publie, avec à la fois PriorityAgent et Agent comme abonnés. Les deux abonnés doivent être 100% autonomes et ne rien partager. Vérifier les pulsations/partager des informations entre ces deux entités distinctes logiques est une mauvaise chose. Pourquoi les avoir séparément en premier lieu alors? S'ils se connaissent mutuellement des «sales secrets», ils devraient être la même chose.

Si votre principale préoccupation est que les messages PriorityAgent ne seront pas traitées si les machines d'hébergement, il sont en baisse, et veulent utiliser les machines d'hébergement Agent comme une sauvegarde, il suffit de déployer PriorityAgent là aussi. Une machine peut exécuter plus d'un point de terminaison. De cette façon, vous pouvez tirer parti des machines supplémentaires, mais vous n'avez pas à vous salir en envoyant la même commande à un point de terminaison logique différent ou en couplant deux points de terminaison logiques différents ensemble via un canal arrière.

+0

Merci pour l'entrée. Déployer 'PriorityAgent' sur les machines' Agent' en tant que sauvegarde est une bonne idée, qui a été bloquée par une exigence du client selon laquelle les machines 'Agent' ne traitent que les messages' PriorityAgent' en cas de panne. Cependant, nous avons été en mesure de modifier les exigences de telle sorte que nous puissions maintenant installer le serveur 'PriorityAgent' sur les serveurs' Agent' et le laisser, ce qui permettrait au client de l'activer manuellement si cela devenait nécessaire. Cela devrait nous permettre de continuer à utiliser NServiceBus d'une manière cohérente avec son intention. – mdk

1

Je m'appelle Dennis van der Stelt et je travaille pour Specific Software, fabricant de NServiceBus. D'après ce que j'ai compris, à la fois PriorityAgent et Agent sont déjà à l'échelle sur plusieurs machines? Ensuite, ils travaillent tous les deux selon consommateurs en concurrence modèle. En d'autres termes, les deux machines essaient de récupérer les messages de la même file d'attente, où une seule va gagner et commence à traiter le message.

Vous parlez aussi de haute disponibilité. Donc, quand PriorityAgent tombe en panne, une autre machine va le ramasser. C'est ce que je ne comprends pas. Pourquoi échouer à Agent, ce qui me semble être un point de terminaison logiquement différent? Si c'est logiquement différent, comment peut-il gérer les messages PriorityAgent? S'il peut gérer le même message, il semble logiquement le même point de terminaison. Alors pourquoi faire la différence entre PriorityAgent et Agent? En outre, SQL Server dispose de toutes sortes de fonctionnalités (comme Always-On) pour s'assurer qu'il ne tombe pas (complètement) en panne. Pourquoi essayer de résoudre des scénarios difficiles avec des solutions de génération personnalisées, alors que SQL Server peut déjà résoudre ce problème pour vous?

Un autre scénario pourrait être que PriorityAgent devrait gérer les cas prioritaires. Quelque chose comme les clients privilégiés ou les clients de grande valeur. Cela est parfois utilisé lorsque (par exemple) beaucoup de commandes (lire: messages) arrivent, mais nous voulons traiter avec des clients de grande valeur plus rapidement que des clients réguliers. Mais en raison de la quantité de messages qui arrivent, les clients de grande valeur se retrouvent également en queue de peloton, avec les clients réguliers. Une solution pourrait être de publier ces messages et d'avoir deux extrémités différentes (avec des files d'attente différentes) souscrites à la fois à ce message. Les deux reçoivent chaque message unique, mais vérifiez s'il s'agit d'un message qu'ils doivent gérer. Le Agent ignorera les clients de grande valeur, le PriorityAgent ignorera le client régulier.

Voici quelques-unes des solutions disponibles en tant que modèles de messagerie standard ou solutions d'infrastructure pour résoudre votre problème. Encore une fois, je ne comprends pas très bien ce que vous cherchez. Si vous souhaitez continuer la discussion peut-être que vous voulez envoyer un courriel à [email protected] et nous pouvons continuer la discussion là-bas.

+0

Merci pour la réponse. J'ai édité ma question pour essayer de clarifier la situation, mais c'est plus proche de votre dernier scénario. 'PriorityAgent' devrait en effet gérer les« ordres »prioritaires, tandis que tout le reste peut attendre sur la file d'attente plus longue' Agent'. Si je vais avec votre suggestion des deux points de terminaison abonnés au message qui ignorent les messages qui ne leur sont pas destinés, comment les machines 'Agent' sauraient-elles que les machines' PriorityAgent' sont arrêtées et doivent commencer à traiter les messages destinés au 'PriorityAgent'? – mdk