J'ai un système où un client (appelons-le ClientA) peut publier des demandes sur un sujet MQTT particulier. Le courtier, si cela est important, est Amazon Web Services. Ensuite, j'ai un autre client (appelons-le MainSubscriber) qui est toujours abonné au même sujet afin qu'il puisse récupérer les demandes de ClientA et faire un travail qui, au final, se transforme en opération de base de données. La base de données, au cas où cela compte, est DynamoDB.
Étant donné que le MainSubscriber peut ne pas être toujours accessible / en ligne, il existe un souhait d'avoir un abonné de basculement pour être la sauvegarde de basculement de l'abonné principal. L'idée est que si l'abonné principal ne traite pas la demande en temps opportun, alors l'abonné de basculement se déclenche et effectue l'opération de travail / base de données équivalente. Le défi est que le «travail» et «l'opération de base de données» qui en résulte ne doivent pas être dupliqués par les abonnés principaux et de basculement.
Voici un schéma d'architecture de système logique pour ce système.
-----> MainSubscriber ----
/ \
ClientA --> Broker ---> Database
\ /
---> FailoverSubscriber --
De toute évidence, un tel système présente certains défis:
- Comment l'abonné principal indique-t-il à l'abonné de basculement qu'il travaille sur la demande?
- Comment l'abonné de basculement détecte-t-il que l'abonné principal n'a pas récupéré la demande et doit commencer à y travailler?
- Comment l'abonné de basculement retient-il ensuite l'abonné principal au cas où il reviendrait soudainement en ligne et reprendrait la demande?
- Comment gérer les problèmes de synchronisation entre les abonnés principaux et les basculements?
Je préférerais ne pas avoir à réinventer la roue si une solution existante existe déjà pour un tel schéma. Donc, ma première question est de savoir s'il y a déjà quelque chose là-bas?
Sinon, je pensais utiliser DynamoDB avec des lectures fortement cohérentes pour servir de médiateur entre l'abonné principal et le basculement. Donc, ma deuxième question est de savoir s'il existe des plans bien établis pour ce faire?
Réponses:
Selon la documentation AWS SQS (comme vous l'avez dit, le courtier est AWS), cela devrait être natif:
Le problème étant de trouver le bon délai de visibilité en fonction de votre temps de traitement maximum.
Vous avez encore une petite chance que les deux abonnés traitent le même message, dans ce cas, votre code d'abonné doit essayer de créer une sortie idempotente pour la base de données (même clé primaire au moins) et doit gérer correctement un échec lors de la tentative d'insertion du même enregistrement.
la source
Vous voudrez peut-être examiner le concept de files d'attente de lettres mortes d'AWS SQS . Depuis les documents AWS:
Ainsi, si vous pointez l'abonné principal pour écouter à partir de la file d'attente normale et l'abonné secondaire pour écouter à partir de la file d'attente de lettres mortes, le problème de basculement doit être résolu.
De plus, avec cela, 1, 2 et 3 de vos problèmes sont pris en charge. Dans ce cas, les abonnés principaux et secondaires n'ont pas besoin de se parler.
En outre, en s'appuyant sur la réponse de Tensibai, assurez-vous que votre code d'abonné est écrit de manière à recevoir un message à la fois si plusieurs abonnés écoutent la même file d'attente en raison de la
visibility timeout
L'inconvénient serait qu'il introduirait un retard dans le traitement, les messages n'entrent dans la file d'attente des lettres mortes qu'après un certain temps.
Donc, au cas où vous ne voudriez pas cela, alors vous pouvez aller de l'avant avec la réponse de Tensibai. Et si vous pouvez tolérer cela, au lieu d'avoir une table Dynamo supplémentaire pour les vérifications d'état, vous pouvez l'utiliser.
la source