当前位置: 主页 > 建站知识 > 软件开发

软件开发架构-从微服务到单体架构,你需要知道的事!

发布时间:2023-06-16 07:06   浏览次数:次   作者:佚名

这个月,我和我的同事们正在开源一个内部的架构治理平台:ArchGuard,我们进行了一系列的遗留系统的迁移工作:

其中,最有意思的一个故事莫过于:从微服务到单体架构。因为,它是一种反主流的形式软件开发架构,又或者是反主流的技术架构。

遗留微服务系统的挑战

在我们经过了一系列的内部会议之后,决定了将 ArchGuard 开源。随后,看到了代码库,我们发现了一系列的挑战:

于是呢,我们重新思考合理的后端服务(微服务)的颗粒度应该是怎样的?所以,参考于过去总结的什么用微服务?以及有多少个微服务更合理?先前的一个结论,类似于:

微服务的数量不超过开发人员的数量。

满足康威定律。微服务与开发团队对齐。

cs架构的软件怎么开发_软件开发架构_j2ee架构与应用开发

两个比萨团队原则 —— 开发团队的人员数量维护在 3 \~ 12 人。一个微服务只由一个开发团队维护。

高内聚,低耦合。单个服务与其它服务依赖少。如:两个服务存在相互调用,耦合度相对较高,可以考虑合为一个服务。

收益大于开销。创建服务的开销是否超过了独立成服务的好处。

你不一定需要微服务。考虑采用 DDD (领域驱动设计)分层架构来划分,以方便未来拆分为微服务。

在这个场景之下,几乎违反了上面的一系列规则。所以,我就回到了上述的 6 中去,采用 DDD 的分层架构模式。每个资源/聚合/服务在各自的包下管理(common 除外):

软件开发架构_j2ee架构与应用开发_cs架构的软件怎么开发

  1. ├── Application.kt

  2. ├── clazz

  3. ├── code

  4. ├── common

  5. ├── config

  6. ├── evaluation_bak

  7. ├── evolution

  8. ├── method

  9. ├── metrics

  10. ├── module

  11. ├── packages

  12. ├── qualitygate

  13. ├── report

  14. ├── report_bak

  15. ├── scanner

  16. ├── scanner2

  17. └── system_info

由于是合并的代码,所以代码中除在于 _bak 还有 scanner2 这样看似重复,又或者是迁移中的代码。

为什么单体更适合当前?

再回到多年以前, Martin Fowler 写了那篇《Monolithic First》,意在告诉人们在团队微服务能力和技术不够成熟的时候,你不应该采用微服务。这里的场景和上述的这个场景并不是一样的。对于系统的最终形态来说,单体并不一定适合这个系统,但是当于当前的我们来说,单体是最合适的。原因诸如于:

总体来说,作为一个开源应用/工具,软件工程的模式受限于其合作模式。所以,常规的软件开发架构,并不一定适用,我们需要一些更好的模式。

cs架构的软件怎么开发_软件开发架构_j2ee架构与应用开发

那么,我们还有别的选择吗?

我们的目标架构是单体吗?

从某种意义上,就当前来说,它是的。但是,如果管理有所不善的话,它会变成一个大泥球架构。回顾一下,一个多仓库/多模块的微服务系统,它与一个单体系统在物理形态上的主要区别在于:

所以,只要我们用相似的形态来构建一个单体应用,那么它在部署形态上就可以变成是微服务架构。简单来说,就是:

从结果来说软件开发架构,便是将系统放置在一种临界状态。以让人们根据自己的需要,做出不同的选择。如在 SaaS 化的时候,这就可以变成微服务的形态,单体部署时,则可以变成单体的状态。唯一麻烦的是,需要开发者对于构建系统有足够的了解,并设计好充足的自动化测试设施。

软件开发架构_cs架构的软件怎么开发_j2ee架构与应用开发

如何迁移 ?

接着,我们就开始合并多个代码仓库,其中的一些

保留历史提交记录的合并。主要是结合 git-filer-repo 来进行过滤和选择路径。

构建配置的全集。对 Application.properties 等进行统一。

使用相同的依赖版本。由于不同的年代的原因,所以选择的依赖版本也有所不同,需要尝试先统一,才能合并代码。

j2ee架构与应用开发_软件开发架构_cs架构的软件怎么开发

解决冲突。因为,只合并了 src 目录下的内容,如果包名有问题,如冲突了,需要重置。类似的问题,还有:Application 重复、Bean 冲突、Service 冲突。

就迁移过程来说,它并不复杂,就是耗时。

还有其它选项吗?

相似的场景,如果一个开发人员多个微服务,并且在不考虑单机部署的情况下,Monorepo 是一个更好的选择,把所有微服务项目的代码放在一个仓库里。

毕竟,Google 都可以把所有的代码仓库放一起,我们又有什么不可以的。当然了,Google 使用的技术原理是不一样的。不过,它能提供一个足够强壮的理由。

其它

回过头来看,对于小的团队来说,单体会不会是更合适的选择?那么大的团队呢?