J'essaie toujours de comprendre la structure des microservices depuis que je suis habitué à une approche monolithique
Supposons que nous essayons de construire un système de réservation extrêmement simplifié Uber. Pour simplifier les choses, disons que nous avons 3 services et une API de passerelle pour le client: Booking
, Drivers
, Notification
et nous avons le workflow suivant:
Lors de la création d'une nouvelle réservation:
Disons que toute la messagerie se fait via un appel http plutôt qu'un bus de messagerie comme kafka pour garder les choses simples.
Donc dans ce cas, je pensais que le service Booking
pouvait vérifier la réservation existante. Mais alors, qui devrait recevoir la liste des pilotes disponibles et la notification? Je pense à le faire au niveau de la passerelle, mais maintenant la logique est en quelque sorte divisée en deux endroits:
Gateway
- obtenir la liste des pilotes disponibles + envoyer des notificationsBooking
- vérifier la réservation existanteEt je suis à peu près sûr que la passerelle n'est pas le bon endroit pour le faire, mais j'ai l'impression que si nous le faisons dans le service Booking
, il devient étroitement couplé?
Pour compliquer les choses, que se passe-t-il si nous avons un autre projet qui veut réutiliser le système de réservation mais avec sa propre logique métier en plus? C'est pourquoi j'ai pensé à le faire au niveau de la passerelle pour que la nouvelle passerelle de projet puisse avoir sa propre logique métier distincte de celle existante.
Je suppose qu'une autre façon de le faire est que chaque projet ait son propre service de réservation qui communiquera avec le service de réservation principal, mais je ne suis pas sûr de la meilleure approche ici :-)
Les gens entendent souvent "micro-service" et pensent "nano-service", ce qui peut créer une certaine confusion. Ce sont micro - services, vous n'avez donc pas besoin d'un service distinct pour chaque entité. Tout ce que vous essayez de faire doit se trouver dans les services booking
et notification
. Vous n'avez pas besoin du service driver
(pour aucune des activités que vous avez décrites).
Obtenir une liste des pilotes disponibles pour book relève du service booking
. Un écueil courant est de ne pas regrouper les activités liées dans le même service, c'est ce qu'on appelle la faible cohérence, et c'est très mauvais. N'oubliez pas que vous regroupez les choses dans un service par domaine de problème et non par entité.
Maintenant, en ce qui concerne la réutilisation, l'avantage d'avoir un micro-service séparé est, maintenant, vous pouvez avoir trois équipes distinctes rendant les applications destinées aux consommateurs. Une équipe pour l'application web html standard, une Android et une application ios. Toutes ces différentes applications peuvent être construites de manière complètement différente et semblent appropriées à leur plate-forme particulière (sans répéter le code). Le code de service booking
est réutilisé par ces trois applications, car les trois applications font des appels http au service au lieu d'avoir leur propre code de réservation.
Un flux de réservation typique ressemblerait à ceci:
booking
pour obtenir une liste des pilotes disponiblesbooking
booking
appelle le service notification
avec les détails de la réservationnotification
envoie une notification au chauffeur, l'informant de la réservationnotification
lorsqu'ils se trouvent à moins d'un kilomètre du client.notification
envoie l'alerte au client que son chauffeur est presque làJ'espère que cela a aidé; rappelez-vous, ce sont des micro-services, pas des nano-services, n'essayez pas de diviser le même domaine problématique. Donc, pour répondre au titre de votre question, lorsque vous conservez un micro-service de la bonne taille, la totalité ou la majeure partie de la logique métier de ce domaine problématique peut vivre dans ce micro-service.
Tout dépend de vos besoins exacts.
Disons que vous avez deux applications pour faire la réservation:
Quant au système de notifications, vous pouvez avoir des microservices abonnés à votre service de réservation pour écouter toute nouvelle réservation. En tant que tel, le microservice de réservation informera tous les abonnés et ils agiront en conséquence.
Le seul problème dans ce type d'architecture est ce qui se passe si quelque chose échoue après la publication de la notification, car les deux microservices ne fonctionnent pas comme deux fonctions s'exécutant dans la même transaction de base de données, vous devrez gérer les erreurs avec élégance et éventuellement rejouer les processus qui ont échoué (automatiquement ou manuellement)
La réponse est simple: ce sont les clients des microservices qui gèrent la logique métier dans une architecture de microservices "purs". Pour le rendre plus facile à comprendre, considérons un exemple encore plus simple. Un service qui renvoie simplement des flux d'octets basés sur un URI. En soi, ce n'est pas terriblement utile. Sans savoir comment les URI contiennent quoi, vous ne pouvez que deviner où tirer les choses. Supposons maintenant que vous disposez d'un microservice différent qui offre une fonction de recherche. Vous envoyez une demande avec une chaîne de requête et elle renvoie des URI. Maintenant, les choses deviennent plus intéressantes. Je peux mettre des références aux URI du premier service dans un index.
Mais encore, nous devons en quelque sorte coordonner entre ces deux. Il existe une réponse simple: vous utilisez un navigateur pour récupérer les URI du service d'index, puis récupérez les données du service de données. Aucun service ne "connaît" l'autre et il n'y a absolument aucun couplage entre eux. Je peux utiliser le service d'indexation avec tout autre service de données et vice-versa.
Ce n'est pas nécessairement le cas que c'est la meilleure approche dans tous les scénarios, mais il y a de nombreux avantages à construire les choses de cette façon, en particulier la réutilisabilité dans des scénarios qui ne sont pas actuellement connus.