Existe-t-il un modèle de conception ou une pratique que je peux utiliser pour aider avec des services qui sont en panne ou en baisse, tandis que d'autres sont stables?
Que se passe-t-il si j'ai trois microservices, et deux d'entre eux sont bons, et l'un meurt en plein milieu d'un POST? Deux obtiendront le POST et un non. Je ne pense pas pouvoir effectuer de transactions car j'expédie mes demandes à un service.
Comment puis-je concevoir pour cela? Je ne veux pas de données orphelines dans diverses bases de données.
Réponses:
Quelques options.
Utilisez un canal de communication persistant
Au lieu de HTTP, déposez les messages dans une file d'attente hautement disponible et persistante. Par exemple Kafka. Tant que le serveur cible devient disponible à un moment donné, il recevra le message.
Vous avez le compromis de provisionner et d'administrer maintenant un sous-système complexe (la file d'attente). Assurez-vous donc d'analyser si cela en vaut la peine.
Interruption et nouvelle tentative
Demandez à l'appelant de conserver la demande qui a échoué (peut-être persistée sur le disque) et réessayez périodiquement. Il est important dans ce cas de faire la distinction entre votre demande provoquant un plantage et le service qui est en panne. Le premier est probablement dû à un bogue et devrait être enregistré ... les nouvelles tentatives ne feront probablement aucune différence tant qu'un correctif n'aura pas été fait.
Détecter et compenser
Une tâche périodique vérifie les conditions de cohérence entre les microservices. Par exemple, les journaux d'échecs remontent pour diriger les requêtes API si nécessaire. S'il découvre un problème (par exemple, il y a une commande mais l'expédition n'a jamais reçu la liste de colisage), effectuez les étapes de compensation. Ces étapes peuvent être la création d'un ticket d'assistance pour une correction manuelle, ou l'envoi d'un e-mail à quelqu'un, ou autre chose.
Envisager des alternatives de conception
Un cas comme celui-ci nécessite probablement une passerelle API pour gérer les appels vers les microservices concernés. De cette façon, vous contrôlez les tactiques utilisées pour atténuer ce problème. Vous ne voulez probablement pas surcharger les clients avec ces détails d'implémentation. Voir Schéma du disjoncteur .
Étant donné que les microservices sont indépendants, il existera toujours un cas de défaillance pouvant entraîner une incohérence. Vous devez être prêt à effectuer des corrections manuelles lorsque cela se produit.
Si vous avez besoin d'une forte cohérence, les microservices ne conviendront pas. Si vous avez toujours besoin d'évolutivité, vous voudrez peut-être examiner le partage où les données associées peuvent être colocalisées sur le même fragment pour des garanties de cohérence. Vous pouvez toujours mettre à l'échelle les E / S en ajoutant des fragments.
Si vous avez besoin d'une cohérence élevée et que vous n'avez pas de problèmes d'évolutivité, utilisez simplement des services monolithiques. Utilisez les bibliothèques comme limites dans votre application pour séparer les préoccupations.
la source
Je pense que ce que vous décrivez est le problème du consensus: vous ne voulez pas vous engager à moins que chaque participant à la transaction distribuée ne dise que l'opération a réussi. La solution simple à cela est le Two Phase Commit. Essentiellement, il met en scène la transaction dans chaque système jusqu'à ce que chacun signale que le transfert a réussi (Phase 1). Si chaque participant à la transaction réussit, chacun est invité à s'engager; si l'un d'entre eux a renvoyé un échec à la place, un retour en arrière est émis (Phase 2). Il y a une ride à cela qui vous mène à la solution de validation triphasée plus complexe. Vous pouvez en lire une bien meilleure description ici:
http://the-paper-trail.org/blog/consensus-protocols-two-phase-commit/
http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/
la source