CODING 代码多仓库实践
关于代码的管理问题已经讨论多年,随着企业业务的复杂度提高、软件行业技术栈的选择度变宽泛,现代软件的代码仓库也变得越来越庞大和复杂。一个中型项目,将测试代码、核心业务代码、编译构建、部署打包等基础设施的代码全部加起来,几十万行都是家常便饭。并且一个项目往往由多个团队进行协作,如何让多团队在对同一个项目的代码进行协作时不会相互干扰、相互制约,也是每个企业研发团队在实践中不断摸索的难题。
多仓库与单仓库
对于上文所说的一些问题,业界已经归纳了常见的代码仓库存放方式,常见的如单仓库和多仓库。大部分企业会针对不同的项目采用不同的仓库管理机制,所以对于企业来说,经常会两种方式并存:
- 单仓库
将所有项目代码存放在一个代码仓库当中,这个好处在于项目的所有开发者可以共享看到项目中的所有代码;在项目规模较小的时候,一个库可以更好地管理和维护,发版本只要统一发布即可;对于持续集成,也只需要针对一个库维护若干条流水线。但再好的实践以及工具都有它适用的范围。Git 已经是非常流行的代码托管工具,但 Git 会把所有历史记录以及代码同步到各个用户的本地机器,所以对于大型项目而言,如果使用单仓库,就意味着某个模块开发者的本地可能有大量冗余代码和提交记录的信息,这个时候拆分成更小的库显得更加合适。
谷歌与 Facebook 就是业界典型的单仓库派代表。作为代码行数已经超过数十亿行、commit 数量累计达到千万次的团队(2015 年的统计数据),如果没有强悍的基础设施,也很难运转顺利。Google 曾发表论文介绍其强大的代码管理系统 Piper 以及客户端工具 CitC,但对于大部分企业来说是否有必要投入如此之大的研发成本去自研一个代码管理系统值得商榷,所以谷歌的实践对于大部分企业来说不一定具备参考性。
*谷歌代码仓库每周的提交数量
- 多仓库
将项目代码进行一定的拆分放在多个库当中,好处就是将代码进行一定的解耦,对于体型较为庞大的项目来说管理上会更加清晰和富有弹性。将代码按照一定逻辑分库之后,仓库与模块有了自描述的特征,让一起协作的开发者可以一目了然。发布源码版本、持续集成构建时,负责各仓库的研发组织可以按照自己的节奏来发布,同时将一些“坏代码”的影响控制在某个仓库中,而不会影响项目全部代码。分库也有要注意的地方,在同一个项目里的代码多多少少都有业务上或者是技术上的联系,比如编译依赖:以一个Java 项目为例,客户端接口的调用代码究竟是直接依赖服务端接口代码的定义,还是间接依赖?如果是间接依赖,那么分库管理是非常方便的,但同时客户端就无法快速感知到服务端接口定义的变化。所以在进行多仓库划分时,要注意划分的一些常用原则。
多仓库在业界使用的非常广泛,在腾讯、华为、阿里的开源项目中我们都能看到,比如腾讯的 Tars 开源项目(RPC 开发框架)就按照不同编程语言以及技术栈进行了分库:包括 Java、Go、PHP 等子项目。作为开源项目,一个清晰的分库可以让开发者更好地协作,避免不必要的沟通成本。
*Tars 的开源项目子仓库
CODING 的多仓库实践
CODING 在多仓库实践上也遇到过问题。由于前端、后端、git-server 三个模块的代码放置在同一仓库中,以至于代码版本的 tag 需要保持同步,制约了各个团队的开发节奏。每个模块的进度都得齐头并进,才能保证最终版本是一致的。尽管它们在业务上紧密相连,但实际上这几个模块本身没有编译依赖,所以在没有多仓库功能时,我们只能建立了三个项目,使用三个项目的代码仓库能力,只集中在一个项目当中进行项目管理工作。
在千呼万唤中,CODING 近期终于正式上线了多仓库功能,我们的开发人员也终于可以告别傻乎乎地使用一个项目进行管理,又用多个项目进行代码仓库管理的尴尬问题,我们将那些没有编译依赖的项目,但在业务上又有联系的代码仓库,放置在同一项目的多仓库下,开发人员无需在多个项目中切换。
多仓库功能一直是 CODING 想要投入做的一个特性。随着近几年 CODING 企业用户的快速增长,CODING 的架构也面临着持续的挑战。如何让交付更加顺滑,让特性更快、更好地服务开发者,是我们进行架构演进的初衷。所以我们在很早之前就开始了容器化、微服务化的规划与实施,而在微服务化的过程当中,包括代码仓库管理在内的研发流程与组织方式也在配套前进着。多仓库这项基本能力就可以让多个微服务独立存放在独立的代码仓库当中,配套独立的持续集成流水线,让架构演进变得水道渠成。我们知道很多企业用户对多仓库有很大诉求,CODING 的多仓库已正式上线,欢迎大家前去体验。
业界常用实践
综上我们可以看到,代码仓库的组织方式往往和人员组织架构息息相关,而且代码库的拆分也往往和软件架构的演进息息相关。在现代软件架构逐渐由单体朝着分布式、微服务演化时,代码仓库和研发团队的粒度也在逐渐变小,从以前的集中式慢慢变为网状。但无论是单仓库还是多仓库,最终目的都是为了让开发者更加高效地进行研发。那究竟该如何选择?笔者总结了几条业界的通用实践来供大家思考:
- 技术栈不同的模块建议多库存放
不同技术栈的编译环境、构建环境、发布环境往往不同,代码之间的硬性依赖也不大,可以考虑分库存放。大部分的开发者还是倾向于在工作中持续使用某一种熟悉的编程语言,所以按照技术栈划分是一个常用的实践。
- 仓库的粒度最好和组织架构相匹配
拆库要拆到什么粒度呢?有些研发组织微服务化后,给每个微服务都分配了一个代码库,随着拆分深入,一个项目积攒了几百个代码库。但一个 two-pizza 团队往往会负责多个微服务,不仅仅是一个。所以建议不要盲目使用大量代码库,避免到后期难以管理,可以考虑按照团队组织来划分代码仓库。
- 拆库并不意味着建立部门墙
不少企业代码拆分之后可能顺便就把团队之间的代码权限也做了划分,建议研发团队慎重考虑。关闭了代码权限就意味着,团队与团队之间不再互相 review 代码,相应的工作上的交流也会逐渐减少。如果读者的企业属于内部开放型氛围的公司,或者想要成为开放型的公司,那么关于此点请三思。
CODING 代码多仓库实践的更多相关文章
- Coding 代码管理快速入门
当项目创建好了之后,我们该如何上传代码到 coding 上呢?Coding 网站使用“ Git 仓库”(类似 github )来管理代码.其操作原理在于:利用 git 服务,将本地的项目目录下的文件同 ...
- Coding 代码管理快速入门(转)
当项目创建好了之后,我们该如何上传代码到 coding 上呢? Coding 网站使用“ Git 仓库”(类似 github )来管理代码. 其操作原理在于:利用 git 服务,将本地的项目目录下的文 ...
- 通过git提交代码到仓库
昨天有一个妹子问我如何在还没有commit之前push本地的代码到仓库,现在写写,希望能够帮到大家. 当我们pull的时候会出现没有代码commit的错误提示,在这种情况下,我们需要再commit之前 ...
- 20145212 罗天晨 《网络对抗》Exp3 Advanced 恶意代码伪装技术实践
恶意代码伪装技术实践 木马化正常软件. 啊哈--原本以为很复杂--然后我看了一下蔡野同学的博客,发现原理竟然如此简单-- 对原先生成病毒的代码稍作修改: 于是--把生成的后门软件改成骗人的名字:这里改 ...
- (转)私有代码存放仓库 BitBucket介绍及入门操作
转自:http://blog.csdn.net/lhb_0531/article/details/8602139 私有代码存放仓库 BitBucket介绍及入门操作 分类: 研发管理2013-02-2 ...
- 20145208 蔡野《网络对抗》Exp3 Advanced 恶意代码伪装技术实践
20145208 蔡野<网络对抗>Exp3 Advanced 恶意代码伪装技术实践 木马化正常软件 思路: 在正常软件包中将原本的程序主文件(平时打开程序用的exe文件)改成dll后缀(或 ...
- 使用scm-manager搭建git/svn 代码管理仓库
使用 scm-manager 搭建 git/svn 代码管理仓库 1.在官网上下载scm-manager 下载地址https://www.scm-manager.org/download/ 2. 配置 ...
- (转载)PyTorch代码规范最佳实践和样式指南
A PyTorch Tools, best practices & Styleguide 中文版:PyTorch代码规范最佳实践和样式指南 This is not an official st ...
- gitee上传代码到仓库步骤(最简洁图文+命令说明)
gitee上传代码到仓库步骤(最简洁图文+命令说明) 目录 1.初始化项目 2.将当前目录下所有需要上传的文件代码等资源添加到缓存区 3. 提交缓存区里面的主要内容到本地仓库 4.添加一个远程仓库的地 ...
随机推荐
- EntityFramework Core 3.0查询
前言 随着.NET Core 3.0的发布,EF Core 3.0也随之正式发布,关于这一块最近一段时间也没太多去关注,陆续会去对比之前版本有什么变化没有,本节我们来看下两个查询. 分组 我们知道在E ...
- Glibc编译报错:*** LD_LIBRARY_PATH shouldn't contain the current directory when*** building glibc. Please change the environment variable
执行glibc编译出错如下图 [root@localhost tmpdir]# ../configure --prefix=/usr/loacl/glibc2.9 --disable-profile ...
- MySql 表索引设计原则
索引的优点 1.加快数据的检索速度,这是创建索引的最主要的原因; 2.通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性; 3.加速表和表之间的连接; 4.在使用分组和排序子句进行数据检索时,可 ...
- 测试访问apiserver状态
目录 前言 创建admin证书和私钥 分发kubeconfig文件 检查集群信息 授权kube-apiserver访问kubelet API的权限 前言 到这里,ETCD集群.kube-nginx + ...
- 使用蓝图构建Flask项目目录
蓝图构建项目目录 什么是蓝图 一个应用中或跨应用制作应用组件和支持通用的模式 蓝图的作用 将不同的功能模块化 构建大型应用 优化项目结构 增强可读性,易于维护 蓝图构建项目目录 定义蓝图 app/ad ...
- shell 替换文本中的某个符号为换行符
替换后为: 0.06774 脚本: :%s/,"/\r/g
- Java修炼——四种方式解析XML_SAX
四种方式解析XML:DOM JDOM DOM4J SAX 先写一个XML栗子: <?xml version="1.0" encoding="U ...
- HTML5基础 实例
<!DOCTYPE html><html> <head> <title>李清照简介</title> </head> <bo ...
- [TimLinux] Python C3 MRO
MRO:Method Resolution Order,即方法解析顺序,是python中用于处理二义性问题的算法 采用过的算法: 1. DFS(深度优先算法) 2. BFS(广度优先算法) 3. C3 ...
- 2018HDU多校训练-3-Problem M. Walking Plan
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6331 Walking Plan Problem Description There are n inte ...