在Github的不同存储库中保留Go微服务

在Github的不同存储库中保留Go微服务,go,github,microservices,Go,Github,Microservices,我在做一个微型服务项目。为此,我希望每个服务都有一个Go包,所有这些都包含在项目的父包中。看起来是这样的: . └── github.com └── username       └── project    ├── service1    └── service2 我认为这种结构允许在包名和路径上遵守Go约定。这样做的结果是,我所有的微服务都在Github上的同一个存储库中结束,因为存储库将位于URL中的深度3。我认为,如果代码库变大,这在将来

我在做一个微型服务项目。为此,我希望每个服务都有一个Go包,所有这些都包含在项目的父包中。看起来是这样的:

.
└── github.com
    └── username
        └── project
            ├── service1
            └── service2
我认为这种结构允许在包名和路径上遵守Go约定。这样做的结果是,我所有的微服务都在Github上的同一个存储库中结束,因为存储库将位于URL中的深度3。我认为,如果代码库变大,这在将来可能会成为一个问题。它还可能增加CI/CD管道的复杂性,例如,对一个服务的更改将触发所有其他服务的生成,并且要克隆的代码将不必要地大


有没有办法避免Go约定和Github工作方式之间的冲突?或者这是一个在CI/CD工作中必须解决的问题?

您现在所说的通常被称为monorepo。虽然我个人喜欢将我的所有项目放在自己的独立存储库中,包括微服务和其他一切,但有许多人支持将公司的所有代码放在一个存储库中。有趣的是,Facebook和Facebook都使用monorepos,尽管必须说他们已经建立了很多奇特的工具来让它为他们工作

需要注意的一件重要事情是,您的存储库与您的体系结构是分开的。它们之间不一定有任何关联。你可以在一个单一的回购中拥有所有的微服务,你可以将一个整体分成几个回购;存储库只是存储和记录代码库的工具,仅此而已

在研究该主题时,以下是从网络上的许多文章中得出的一些优点和缺点:

单一回购优势

即使在微服务中,项目之间共享模块的方便性也常常存在交叉问题 只有一个地方可以查看和了解存在哪些代码-对于拥有大量代码的大公司尤其有用 简化自动化和手动代码审查过程 简化文档,而不是从多个断开连接的回购中提取 单一回购协议的缺点

庞大的代码库可能对本地用户的签入/签出造成挑战/缓慢 如果没有非常明确、严格的指导原则,很容易导致产品之间的紧密耦合 部分发布需要稍微复杂一些的CI/CD工具 根据存储库平台的不同,非常大的代码基可能会影响性能 以及monorepo的优点和缺点,特别是与切换到具有微服务体系结构的monorepo有关。有很多支持和反对monorepo的链接


与编程中的许多其他事情一样,尤其是在SOA中,适合您的解决方案取决于许多只有您才能确定的因素。主要的收获是,无论是大公司还是小公司,在这两种选择中都取得了成功,因此,请谨慎选择,但不要太担心。

如今,你所说的是通俗的monorepo。虽然我个人喜欢将我的所有项目放在自己的独立存储库中,包括微服务和其他一切,但有许多人支持将公司的所有代码放在一个存储库中。有趣的是,Facebook和Facebook都使用monorepos,尽管必须说他们已经建立了很多奇特的工具来让它为他们工作

需要注意的一件重要事情是,您的存储库与您的体系结构是分开的。它们之间不一定有任何关联。你可以在一个单一的回购中拥有所有的微服务,你可以将一个整体分成几个回购;存储库只是存储和记录代码库的工具,仅此而已

在研究该主题时,以下是从网络上的许多文章中得出的一些优点和缺点:

单一回购优势

即使在微服务中,项目之间共享模块的方便性也常常存在交叉问题 只有一个地方可以查看和了解存在哪些代码-对于拥有大量代码的大公司尤其有用 简化自动化和手动代码审查过程 简化文档,而不是从多个断开连接的回购中提取 单一回购协议的缺点

庞大的代码库可能对本地用户的签入/签出造成挑战/缓慢 如果没有非常明确、严格的指导原则,很容易导致产品之间的紧密耦合 部分发布需要稍微复杂一些的CI/CD工具 根据存储库平台的不同,非常大的代码基可能会影响性能 以及monorepo的优点和缺点,特别是与切换到具有微服务体系结构的monorepo有关。有很多支持和反对monorepo的链接

与编程中的许多其他事情一样,尤其是在SOA中,适合您的解决方案取决于许多只有您才能确定的因素。主要的收获是
大公司和小公司在这两种选择中都取得了成功,而且中间有很多选择,所以请仔细选择,但不要太担心。Go项目所依赖的版本控制子包可以通过跟踪来实现。因此,我们鼓励使用Go模块将子包迁移到自己的git回购中

如果您的大多数解决方案都是用go编写的,我建议您充分利用

这篇博文解释了如何管理Go模块的Go.mod,它与包依赖项及其相关的版本git标记有关:


Go项目所依赖的版本控制子包可以通过跟踪进行跟踪。因此,我们鼓励使用Go模块将子包迁移到自己的git回购中

如果您的大多数解决方案都是用go编写的,我建议您充分利用

这篇博文解释了如何管理Go模块的Go.mod,它与包依赖项及其相关的版本git标记有关:


有一种很好的方法可以使用单独的存储库和Go微服务:Go插件。简言之:

构建实现共享功能的基础映像。 让基础图像在容器中的某个位置查找 在派生图像中,将功能编译为Go插件,并将其放置在基础图像可以找到的位置。
对于Go/gRPC,我已经提出了一个很好的方法来处理单独的存储库和Go微服务:Go插件。简言之:

构建实现共享功能的基础映像。 让基础图像在容器中的某个位置查找 在派生图像中,将功能编译为Go插件,并将其放置在基础图像可以找到的位置。
对于Go/gRPC,我已经指出。

根据12Factor,每次回购都应该是一个应用程序。一对一关联。如果项目目录中有所有服务,则存在紧密耦合。如果您希望在将来使用不同的语言或新的堆栈对其中一个服务进行授权,该怎么办?它不会编译,对吗?根据项目的性质,包共享一些公共资源,这就是为什么它们被分组在同一路径下。但每一个都有一个目的。我认为这并不是微服务的典型特征。我不介意将每个服务作为一个Go模块,它可以移动到路径之外,或者单独用于另一个项目,它没有那么紧密的耦合。要遵循微服务体系结构,应该将每个n-every服务分离到一个单独的git repo。以及单个CI/CD管道。我注意到本次讨论的答案中没有提到go模块。带有go模块的子包版本控制使用git提交标记。如果您想要控制某个子包的特定版本,则该子包需要位于其自己的git repo中。基本上,一个git回购包含了你的应用程序&所有子包都没有go模块提供的粒度。根据12Factor,每个回购都应该是一个应用程序。一对一关联。如果项目目录中有所有服务,则存在紧密耦合。如果您希望在将来使用不同的语言或新的堆栈对其中一个服务进行授权,该怎么办?它不会编译,对吗?根据项目的性质,包共享一些公共资源,这就是为什么它们被分组在同一路径下。但每一个都有一个目的。我认为这并不是微服务的典型特征。我不介意将每个服务作为一个Go模块,它可以移动到路径之外,或者单独用于另一个项目,它没有那么紧密的耦合。要遵循微服务体系结构,应该将每个n-every服务分离到一个单独的git repo。以及单个CI/CD管道。我注意到本次讨论的答案中没有提到go模块。带有go模块的子包版本控制使用git提交标记。如果您想要控制某个子包的特定版本,则该子包需要位于其自己的git repo中。基本上,一个单一的git回购协议容纳了你的应用程序&所有的子包都没有go模块提供的粒度。