9
votes

organisation grpc dans les microservices

Je crée un système utilisant une architecture de microservices. Il existe deux microservices A et B , chacun vivant dans son propre référentiel.

Il existe un fichier user.proto contenant la définition de protobuf et les signatures de méthode gRPC. A utilise user.pb.go généré comme serveur. B utilise user.pb.go comme client (de A ).

Une façon de structurer cela est avec la définition de proto apparaissant dans A , avec B ayant une dépendance de code sur A :

 A
 ├── service.go
 └── pb
     └── user.pb.go
 B
 ├── service.go
 └── pb
     └── user.pb.go
 P
 └── user.proto

Une autre façon est d'avoir un autre repo P contenant les définitions du proto, avec A et B dépendant du nouveau repo:

 A
 └── service.go
 B
 └── service.go
 P
 ├── user.proto
 └── user.pb.go

A-->P
B-->P

Ou le nouveau dépôt peut contenir uniquement le fichier proto, avec du code généré à la fois en A et B:

 A
 ├── pb
 │   ├── user.proto
 │   └── user.pb.go
 └── service.go
 B
 └── service.go

B-->A

Quelle est la meilleure approche ici?


1 commentaires

microservices ne signifie pas microrépôts.


3 Réponses :


0
votes

La deuxième façon est meilleure.

Pourquoi? Parce que lorsque vous ajoutez le service C, il tombe naturellement en ligne avec A & B. Sans aucune modification du code de chemin d'importation nécessaire pour aucun des composants existants.

Oui, la troisième méthode peut le revendiquer, mais elle duplique le user.pb.go généré sur chaque micro-service. Mieux vaut consolider pour éviter les doubles emplois.

Vous pouvez également utiliser la fonctionnalité des packages internes de go au niveau supérieur de votre dépôt (c'est-à-dire au niveau A & B). Renommer P en internal garantit que ce sous-paquet peut être utilisé par A , B (ou C etc.) mais n'est pas une invitation pour d'autres paquets tiers à référencer ce paquet «interne».


4 commentaires

N'est-ce pas également vrai pour la troisième voie?


@kskyriacou a mis à jour la réponse et est également inclus maintenant, le sous-package P prête à la fonctionnalité des packages internes de go.


Je pense que vous avez mal compris: A, B & P sont tous des dépôts séparés


Tout ce qui précède s'applique toujours. Les repo sont simplement des chemins, cela n'affecte pas la façon dont le processus de go build voit.



0
votes

Je pense que la bonne réponse dépend de l'ampleur de votre projet.

Pour les petits projets ou projets qui peuvent être utilisés en dehors de votre équipe (par exemple, des produits open-source ou même propriétaires livrés avec le SDK à d'autres équipes), je préférerais la première approche. Si vous ne fournissez pas de code généré (fichiers pb.go ) dans le référentiel principal, vos utilisateurs ne seront pas satisfaits, car protoc est très loin d'être un outil convivial.

En variante de la première option, je rappelle des projets avec un référentiel unique pour tous les microservices (dit "monorepo"). Ils placent les fichiers pb.go générés directement dans vendor référentiel du vendor .

Pour les grands services Web avec un backend de microservice riche, le second serait une meilleure option. Vous obtiendrez un référentiel unique avec la définition complète de votre API. Cela améliorera la cohérence de votre API et vous aidera à configurer le cycle de publication. Vous pouvez ou non mettre pb.go avec des fichiers proto , cela dépend de vos besoins, mais nous ne le faisons généralement pas .


0 commentaires

1
votes

Si votre équipe ne préfère pas le monorepo, je pense que la troisième option est la plus appropriée. 1 repo pour les fichiers proto. Ensuite, il peut être inclus en tant que sous-module git vers A et B (si vous utilisez git). A et B peuvent avoir leur propre script de protocole et les fichiers protobuf générés dépendent des langages de programmation qu'ils utilisent.


1 commentaires

Je suis d'accord, le code généré sera désynchronisé s'il est stocké dans un référentiel, plus il doit être généré en fonction de la langue, donc générer à l'avance suppose déjà une langue, à moins que vous ne génériez pour toutes les langues nécessaires à l'avance.