这段时间在研究bilibili泄露出来的源码,发现bilibili虽然使用了微服务的设计理念但是所有服务都是放在同一个仓库底下的,而我司和bilibili恰恰相反,我司所有项目都是分开独立的,也出现了一些问题。于是就产生了好奇并在网上进行了探索随后产生了这篇文章。

本文会尝试回答下面几个问题:

  1. 什么是单体仓库(mono-repo)?
  2. 为什么 Google/Facebook/Bilibili 采用单体仓库?
  3. 单体仓库(mono-repo)和多仓库(multi-repo)分别解决了哪些问题?
  4. 单体仓库(mono-repo)和多仓库(multi-repo)在解决问题的同时又引入了哪些问题?

为什么要区分单体仓库和多仓库?

在介绍单体仓库和多仓库前,我们先了解一下应用的类型,了解一下为什么要区分单体仓库和多仓库。

1. 单体应用

在早期,实际上是不用区分单体仓库和多仓库的,因为在早期的时候一个应用就把所有功能打包了。哪怕使用多个仓库也是根据公共模块方式来区分,仓库数量也是比较少的。这时候的应用我们一般叫他单体应用。主要的特点就是一个程序就打包所有功能,全家桶。

这样的开发模式有很多优点,如:

  1. 易于理解项目整体。开发人员可以把整个项目加载到本地的 IDE 当中,进行 code review,方便开发人员把握整体的技术架构和业务目标。
  2. 易于集成和部署。所有的代码在一个仓库里面,不需要特别的集中管理和协调,也可以直接在本地部署调试。
  3. 易于重用。所有的代码都在一个仓库中,开发人员开发的时候比较容易发现和重用已有的代码,而不是去重复造轮子。
  4. 开发人员(通过 `IDE 的支持)容易对现有代码进行重构,可以抽取出一些公共的功能进一步提升代码的质量和复用度。
  5. 易于规范代码。所有的代码在一个仓库当中就可以标准化依赖管理,集中开展 code review,规范化代码的风格。

但是随着单一应用功能的拓展,应用仓库无限制变大也带来了很多缺点,如:

  1. 开发效率大幅降低,所有的开发人员在一个项目改代码,递交代码相互等待,代码冲突不断。
  2. 代码维护性变差,随着功能以及代码量的大幅增加,所有代码功能耦合在一起,新人不知道何从下手。
  3. 构建时间过长,任何小修改必须重新构建整个项目,这个过程往往很长。
  4. 稳定性太差,任意一个功能出现问题,可以导致整个应用挂掉。
  5. 扩展性达不到要求,所有功能都在一起,无法简单的横向扩展,容易受限于物理机器的配置。

2. 微服务应用

既然单一应用的问题是由于后期功能过多,应用复杂度上升产生的。那是否可以通过将单体应用拆解成无数的小应用来避免这些问题呢?

实际上后来大佬提出的微服务这个概念就类似于上面的思路,通过将一个大型应用拆分成无数个服务。每个服务有自己的代码文件,单独部署,然后共同组成一个应用程序。

需要注意的是这里的"微"不是指的代码行数,而是说服务的功能限定到单个功能。

微服务相比单体应用最大的好处是可以独立的开发测试部署和扩展。

既然单体应用一般采用单体仓库,那么微服务的代码仓库又是如何组织的呢?实际上关于这点网络上讨论的不是很多,而我们公司选择的就是一个服务一个仓库。

实际上在写这篇文章之前,我也一直以为这样是微服务的最佳实践。但是bilibili的源代码告诉了我们另一个选择,单体仓库(mono-repo

单体仓库和多仓库

实际上,针对微服务代码的仓库组织,业界一直有两种主要的实践:

  1. 一种是多仓库(multi-repo),在微服务中就是每个服务一个源码仓库。
  2. 另一种叫单体仓库(mono-repo),虽然应用采用的微服务架构,但将所有源码放在同一个仓库。

从左到右依次为: 单体应用单体仓库(monolith),微服务多仓库(multi-repo),微服务单体仓库(mono-repo)。

首先需要肯定的是,单体仓库和多仓库两种方案能同时存在,一定是各有利弊的,希望大家不要将自己锁定到一种方案上,软件开发中没有银弹,选择最合适的就是最好的。

1. 多仓库

多仓库为我们带来了如下好处:

  1. 每一个服务都有一个独立的仓库,职责单一。
  2. 代码量和复杂性受控,服务由不同的团队独立维护、边界清晰。
  3. 单个服务也易于自治开发测试部署和扩展,不需要集中管理集中协调。
  4. 利于进行权限控制,可以针对单个仓库来分配权限,权限分配粒度比较细。

但同时,多仓库也存在着以下的问题:

  1. 项目代码不容易规范。每个团队容易各自为政,随意引入依赖,code review 无法集中开展,代码风格各不相同。
  2. 项目集成和部署会比较麻烦。虽然每个项目服务易于集成和部署,但是整个应用集成和部署的时候由于仓库分散就需要集中的管理和协调。
  3. 开发人员缺乏对整个项目的整体认知。开发人员一般只关心自己的服务代码,看不到项目整体,造成缺乏对项目整体架构和业务目标整体性的理解。
  4. 项目间冗余代码多。每个服务一个服务一个仓库,势必造成团队在开发的时候走捷径,不断地重复造轮子而不是去优先重用其他团队开发的代码。

2. 单体仓库

单体仓库的优势:

  1. 易于规范代码。所有的代码在一个仓库当中就可以标准化依赖管理,集中开展 code review,规范化代码的风格。
  2. 易于集成和部署。所有的代码在一个仓库里面,配合自动化构建工具,可以做到一键构建、一键部署,一般不需要特别的集中管理和协调。
  3. 易于理解项目整体。开发人员可以把整个项目加载到本地的 IDE 当中,进行 code review,也可以直接在本地部署调试,方便开发人员把握整体的技术架构和业务目标。
  4. 易于重用。所有的代码都在一个仓库中,开发人员开发的时候比较容易发现和重用已有的代码,而不是去重复造轮子,开发人员(通过 IDE 的支持)容易对现有代码进行重构,可以抽取出一些公共的功能进一步提升代码的质量和复用度。

单体仓库的劣势:

  1. 单体仓库基本放弃了对读权限的限制,开发人员可以接触到项目所有代码,Bilibili的源代码泄露也印证了这个问题。
  2. 对于写权限,单体仓库也是有着自己的解决方案,比如OWNERSCODEOWNERS等,但相比多仓库还是差了一些。
  3. 单个服务的开发测试部署和扩展,需要集中管理集中协调,降低了微服务单个服务的自治程度。
  4. 代码量和复杂性不受控,随着公司业务团队规模的变大,单一的代码库会变得越来越庞大复杂性也呈极度的上升,容易受团队能力及开发流程等影响导致结果不可控。
  5. 想要玩转单体仓库,一般需要独立的代码管理和集成团队进行支持,加上配套的自动化构建工具来支持。某些方面已经出现了开源的方案,比如 Google 自研的面向单体仓库的构建工具 Bazel:https://bazel.build/ 和 FacebookBuck:https://buck.build/ 。但还是需要团队进行整合。

世界上采用单体仓库管理源码的公司实际并不少,比如: GoogleFacebookTwitter 这些互联网巨头。可以看到,虽然这些公司系统庞大、服务众多,内部研发团队人数众多,但是采用单体仓库也很好的解决了业务需求。

总结:

微服务架构并不是主张所有的东西都要独立自治,至少代码仓库就可以集中管理,不要让先入为主的观念影响你的判断,根据实际需要选择最合适的方案。

初创公司的话,在公司早期并且服务不是特别多的情况下,采用单体仓库比较合适。这样也容易养成团队统一的代码风格,过早的分而治之容易导致团队各自为战,代码风格散乱等问题。

单体仓库与多仓库都有哪些优势劣势,微服务选择哪种方案比较好?相关推荐

  1. 微服务的4种部署策略,你都清楚吗?

    程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 6 分钟. 来自:cnblogs.com/Courage129/p/14498788.html 在项目迭代的过程中,不可避免需 ...

  2. 单体应用架构——垂直应用架构———分布式架构———SOA架构———微服务架构

  3. 从单体迁移到微服务的几种模式

  4. DDD微服务架构设计第三课 DDD领域中的聚合、工厂和仓库、限界上下文

    05 聚合.仓库与工厂:傻傻分不清楚 上一讲,我们知道了,要将领域模型最终转换为程序设计,可以落实到 3 种类型的对象设计,即服务.实体与值对象,然后进行一些贫血模型与充血模型的设计思路.但这远远不够 ...

  5. 容器化技术与微服务结合---结合springcloud微服务框架进行部署(含切换成阿里云docker仓库)(五)

    目录 系列 更换成阿里云仓库 开通阿里云镜像服务 创建仓库 本地k8s切换成阿里云的镜像仓库 测试阿里云镜像 准备简单的微服务 eureka 应用配置 k8s配置: demo-a 应用配置 k8s配置 ...

  6. 系统由单体架构到微服务架构到底是如何演进的?

    随着互联网的发展,互联网企业的业务也在不断的飞速发展,进而导致系统的架构也在不断的发生着变化.总体来说,系统的架构大致经历了:单体应用架构->垂直应用架构->分布式架构->SOA架构 ...

  7. 面试都在问的微服务,一文带你彻底搞懂!

    来自:后端技术学堂 单体式应用程序 与微服务相对的另一个概念是传统的「单体式应用程序」( Monolithic application ),单体式应用内部包含了所有需要的服务.而且各个服务功能模块有很 ...

  8. 微服务系列(七):将单体应用改造为微服务

    编者的话|本文来自 Nginx 官方博客,是「Chris Richardson 微服务」系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第三篇描述了微服务架构模块 ...

  9. 为何从单体架构迁移到微服务这么难?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 面对微服务如火如荼的发展,很多人都在了解,学习希望能在自 ...

最新文章

  1. Pycharm去掉项目所有 # 注释
  2. 线段树 ---- CF1004F Sonya and Bitwise OR(线段树上分治合并区间信息 + or 前缀和的log性质)
  3. Linux内存管理 (2)页表的映射过程
  4. JS魔法堂:doctype我们应该了解的基础知识
  5. Solartimes共识——View(20060502)和Form(20060501)
  6. 2016/06/22 中色启动筹码分析作业
  7. Linux学习笔记:用户、用户组、文件系统和网络
  8. css实现图片虚化_什么? CSS 阴影竟然还有这种骚操作 ?
  9. 应用联合服务 云计算拉近应用和操作距离
  10. TensorFlow 的简化接口Scikit Flow
  11. 华为数通HCNA学习资料
  12. [原创]浅析汇编之堆栈平衡
  13. PCD文件的rgb格式
  14. DataBinding 的集成:点击AIL+Enter , 没有出现【convert to data binding layout】怎么办?
  15. stormzhang的自我介绍
  16. 这几个excel神操作,让你从入门到大神 ,涨完工资再来谢我……
  17. 埃及通信和信息技术部使用 OpenText ECM 内容服务平台为电子政务转型奠定基础
  18. mysql5.5手册读书日记(4)
  19. mangabz漫画网鬼灭之刃漫画爬虫
  20. uni-app 多端本地图片转base64 本地图片转base64

热门文章

  1. linux中的哲学思想
  2. razor生成html,MVC Razor模板引擎输出HTML或者生产HTML文件
  3. 立创eda入门(1)——网络标签问题
  4. Microsoft Excel 教程:如何在 Excel 中创建下拉列表?
  5. Autodesk 2020版本 激活时一直重复出现激活与输入序列号步骤,不出现输入激活码页面的通用解决办法
  6. c语言程序设计中国铁道出版社课后题答案,C语言程序设计(中国铁道出版社) 第4章 数组练习题答案003.doc...
  7. 基于ATMEGA8A_AVR单片机及MAX6675的K型热电偶proteus仿真
  8. 北京黑马JavaEE就业32期(20160717面授)
  9. 日系简约商务通用PPT模板
  10. fcitx五笔大字集乱码