微服务中的grpc组织

时间:2019-05-10 17:42:09

标签: architecture microservices grpc proto grpc-go

我正在使用微服务架构创建系统。有两种微服务AB,它们分别位于各自的存储库中。

有一个user.proto文件,其中包含protobuf定义和gRPC方法签名。 A使用生成的user.pb.go作为服务器。 B使用user.pb.go作为A的客户端。

一种结构化方法是在A中出现原型定义,其中BA具有代码依赖性:

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

B-->A

另一种方法是拥有另一个包含原型定义的仓库P,其中AB取决于新仓库:

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

A-->P
B-->P

或者新的仓库只能包含原始文件,并且在A和B中都生成了代码:

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

这里有什么更好的方法?

3 个答案:

答案 0 :(得分:0)

第二种方法更好。

为什么?因为添加服务C时,它自然会与A&B内联掉线。无需为任何现有组件更改导入路径代码。

是的,第三种方法可以主张这一点,但是它在每个微服务之间复制了生成的user.pb.go。最好进行合并以避免重复。

您还可以在仓库的最高级别(即A和B级别)使用go的internal packages功能。将P重命名为internal可确保AB(或C等)可以使用此子包,但不会邀请其他第三方包引用此“内部”程序包。

答案 1 :(得分:0)

我认为正确的答案取决于您的项目规模。

对于小型项目或可能在团队之外使用的项目(例如,SDK附带的开源或专有产品提供给其他团队),我更喜欢第一种方法。如果您没有在主存储库中提供生成的代码(pb.go文件),那么您的用户将不会满意,因为protoc远非一个用户友好的工具。

作为第一种选择的变体,我回顾了所有微服务都具有单个存储库的项目(所谓的“ monorepo”)。他们将生成的pb.go文件直接放入vendor存储库中。

对于具有丰富的微服务后端的大型Web服务,第二个将是更好的选择。您将获得一个具有完整API定义的存储库。这将改善API的一致性,并帮助您设置发布周期。您可能会或可能不会将pb.goproto文件一起放置,这取决于您的需要,但是我们通常会don't

答案 2 :(得分:0)

如果您的团队不喜欢monorepo,我认为第三个选择是最合适的。 1个原始文件的仓库。然后,它可以作为git子模块包含在A和B中(如果您使用的是git)。 A和B可以拥有自己的协议脚本,生成的protobuf文件取决于他们使用的编程语言。