DevOps转型下的研发策略该如何设置?

2022-04-24 17:13:48 浏览数 (1)

作为一名研发人员,你的工作中有没有遇到类似的问题:分支如何管理才能更好地提升研发和CI效率?单元测试如何做才能更高效?代码评审要不要做,审什么?想上容器,有哪些好的实践可以借鉴?好的策略可以使开发工作事半功倍,让软件交付提质增效。

本文由资深DevOps咨询顾问段亚浩,来为大家详解如何通过对分支策略、代码质量/规范、云原生支持等多个方面的加强和优化,让开发人员提升研发效能。

段亚浩老师说道,研发端需要注意的事项不少,例如规范和规则等。本文我们先分享分支策略、单元测试、代码质量检查、代码评审、容器化策略这几个方面,后续有机会的话老师会再给大家分享其他的策略。通过这些策略,希望能加快交付的速度,同时保证产品的质量。

01. 分支策略

1. 代码管理工具:SVN or Git

大家用的比较多的代码管理工具有SVN和Git,Git是业界主流的代码管理工具。Git的优势有很多,比如在分支管理这块灵活快速、与Linux和Docker一脉相承等。由于同是Linus的代表作品,Git和Linux在文件管理方面有很多类似的地方。又如现在很火的云原生,未来你如果需要用到容器Docker,Git和Docker的命令也很相似,使用起来学习成本较低。不仅如此,将来如果要打通DevOps工具链的话,使用Gitlab也更加方便些。

▲ SVN vs Git▲ SVN vs Git

2. 为什么要使用分支

既然说的是分支策略,那么接下来就谈谈在什么场景下,需要用到分支。我们来设想下面几种情况:

  • 我们在基于一个稳定的版本在进行开发,突然在稳定版本上有一个紧急的bug需要我们解决。
  • 我们在软件中加入了一个小的特性,但是开发到一半的时候,发现开发组的另一个的想法更有创意,所以我们想废弃自己的更改。
  • 团队想在软件中同时加入多个特性,但是希望并行开发,而不是依次开发。

针对以上几种典型场景,就建议我们使用分支来处理:

  • 如果稳定版本有一个紧急bug需要处理,那么我们就可以基于稳定版本分支创建一个新分支,切换到该分支并修改bug,经过测试、发布之后,我们将该分支合并到稳定分支即可。
  • 假设我们想废弃正在开发的某个特性,如果该特性在一个单独的分支上,只需要简单的删除该分支即可。
  • 如果我们想并行开发多个特性,我们可以创建多个分支,分别开发,然后将每个分支都合并到稳定分支上即可。

关于Git分支的理解和交互式学习Git分支,欢迎点击阅读原文,下载ppt查看。

3. 分支管理模式分类

分支管理模式主要分为两种类型:基于主干开发的Trunk Based Development(TBD)和基于分支开发的Feature Branching。

TBD(主干开发模式)的优势是所有最新代码都在主干上。缺点也很明显,由于所有代码都在主干上,发布的时候若没有遵循规则,则容易出现问题。尤其是多版本并行开发的时候,可能会出现不是这个版本的代码也被提交到主干上来了。当然,也有方法可以减少类似错误的发生:比如使用特性开关、或者做相应的规范约束,即约定好不在目前发布版本里的功能就尽量不要在目前的时间段内进行提交。不过这样可能会对开发进度有所影响。TBD的关键点为:

  • 同一个产品开发的所有人员共享一个Repository,有一个共同的trunk。单一Developer或是Developer团队可以有自己的private branch,所有修改最后都会回到主干。
  • 只有在Release时才会有官方的分支,一般Developer不能对Release Branch做动作,只有Release Engineer可以更动Release Branch,当Release Branch完成它的任务,就会被砍掉。
  • Bug先在trunk修好,之后把Commit合并到Release Branch,而不是在Release Branch修好再整合到trunk,这样可以把修改Release Branch的人限制在最小程度。
▲ TBD模型图(图片来源网络,如有侵权请联系删除)▲ TBD模型图(图片来源网络,如有侵权请联系删除)

分支开发模式的代表是GitFlow。GitFlow模型是若干分支开发模式的集大成者,包含一个主干分支、一个开发分支、许多的特性分支、许多的发布分支和 Hotfix 分支,以及许多繁琐的合并规则。由于对每个阶段的每项操作定义十分明确,它曾经是很多重视流程的企业眼里的香馍馍。但它使用起来并不容易,大量的合并冲突和对集成测试不友好也是它被诟病最多的地方。

GitFlow分支模型里有两个常驻分支:develop分支和master分支。所有的开发过程是基于develop去拉特性分支(feature branches),然后开发人员再在特性分支上进行开发,开发完成自测后再合并到develop分支上。此时,develop就相当于一个集成分支,集合所有最新的代码。在某一个时间节点,基于develop分支再拉出一个发布分支(release branches),并在测试环境下做测试,测试通过的代码会同时合到master和develop分支上,并在master分支上打一个标签tag。(如下图)在生产环境下,如果出现故障,就基于该版本的tag拉出一个hotfixes分支进行修复。

▲ GitFlow分支模型图▲ GitFlow分支模型图

关于不同分支策略分析、优缺点和适用场景,在幻灯片第12张,欢迎点击阅读原文下载查阅。

02. 单元测试

根据以往咨询项目时的经验来看,很多公司都是不做单元测试或者很少做单元测试的,因为觉得单元测试代码编码工作量大、投入高,短时间内难以满足单测覆盖率要求,且投入产出比不高。但单元测试是研发阶段保障代码功能的有效手段,如果缺了单元测试,后期接口测试和系统集成测试阶段问题会很多,造成研发和测试反复多次交接,反而对交付速度更不利。所以还是建议将质量左移,在前期投入更多时间和精力来做单元测试,其实它的投入产出比是更高的。建议大家可以引入一些自动化工具进行协助:

分享三个自动代码生成工具,所依赖的环境、支持语言等详见下图,推荐尝试一下EvoSuite:

03. 代码质量检查

SonarQube是一款大众较为熟悉的代码检查软件。SonarQube可以集成一些常用的工具比如PMD、Checkstyle、findbugs、阿里p3c。待工具都准备好以后,由架构师评审筛选代码规则,确定形成组织级的代码扫描规范规则集。

尽管Sonar被大家所熟知,但其在21年第4季度时爆出漏洞,以及国家对金融行业使用开源软件的管理要求,已经有企业在考虑国产化软件。除此之外,信创适配在近几年也是国家政策所号召的方向。在此,我们介绍一款在蓝鲸DevOps平台中的代码扫描工具CodeCC,它是基于腾讯多年沉淀的代码扫描规则所打造。CodeCC是通过静态代码分析,找出代码隐藏的错误和缺陷,帮助开发人员快速解决质量问题和安全漏洞,助力交付高质量。所具备的优势诸如:

语言:提供支持主流语言代码扫描的多种扫描插件;

趋势:统计代码扫描、历史趋势比较;

建议:提供告警详情及错误代码位置,规范化的修复指导,降低修复成本;

效率:支持增量扫描,缩短扫描的时间;

…..

扫描出代码问题仅仅是第一步。如果能够把扫描和流水线结合起来,即当问题超过某一个标准或阈值流水线就会自动中断,便能让质量保证自动化。因此,可以把这些标准定义成红线规则,通过蓝鲸DevOps平台,与流水线结合,确保交付物的准出。

04. 代码评审

可能很多人会问,代码质量提高以后,代码评审还有必要吗?当然是有的!很多公司不搞评审的常见原因有:需求变化太快、项目时间紧张、领导更关注业务交付,不太明白代码评审的意义等。

但我们认为,这些都没办法抵消代码评审的重要性,因为心思再慎密的人也有疏漏的时候,代码多review可以避免一些问题。并且,代码评审对代码的结构调整很有好处。如果一个reviewer看不懂你写的代码,那就不要指望当你离开后有多少人可以看懂了,维护成本会更大。第三,代码评审还可以促进团队之间相互交流,不会因为别人不在做这一块就不知道这些代码的作用。再小的团队都有必要做审查,除非这个团队就只有一个人。

其实,大可不必对代码评审过于烦恼。因为代码规范检查工具可以很轻松的完成大部分机械的检查工作,剩下需要人工做的仅仅是评审代码设计及可维护性,比如:

  • 代码逻辑间是否足够的解耦
  • 复杂逻辑是否有明确的注释
  • 可能出异常的逻辑是否有异常处理

蓝鲸DevOps平台已经把代码检查单进行了线上化,在进行代码评审时,可根据检查单勾选所需检查项即可。想了解更多平台的功能,欢迎扫描文末二维码进行咨询试用。

▲ 代码检查界面展示▲ 代码检查界面展示

05. 容器化策略

现在容器的引入也越来越多,因为容器的优势很明显:能够解决环境不一致的问题。其他的优势还包括使得持续交付和部署更方便、让启动时间更加快速、资源利用更高效等等。

容器化的七大原则:不要在容器中存储数据、不要发布两份应用、清除不必要的包和文件、不要在容器中运行多个进程、不要在镜像中存储凭据,使用环境变量、使用非root用户运行、不要依赖IP地址。

1. 容器最佳实践一:Dockerfile

在镜像这块,我们希望它尽量的小。预期诸如能够快速构建镜像、更快拉取镜像、解决存储空间。具体的做法:使用微镜像、减小镜像层数、避免不必要包安装、复用Cache、使用Volume、清理yum/apk cache。

2. 容器最佳实践二:容器应用

容器在运行时,同样也需要注意几个问题:

① 镜像要尽可能的小

通过清理临时文件,并避免安装不必要的软件包来构建小尺寸镜像。这样能够减少容器的尺寸,构建时间和复制容器镜像的网络传输时间。

② 支持任意用户ID

避免使用sudo命令或要求特定用户名运行你的容器。

③ 标记重要的端口

虽然可以在运行时指定端口号,然而通过使用EXPOSE命令在运行的时候指定,则可以让镜像的使用者更轻松。

④ 为持久数据使用卷

对容器摧毁之后还需要保存的容器数据的情况,必须将数据写入一个数据卷。

⑤ 设置镜像元数据

以标签和注释形式存在的镜像元数据可以使您的容器镜像更加实用,从而为使用您容器的开发人员提供了更好的体验。

⑥ 使主机和镜像同步

一些容器应用需要容器在某些属性(如时间和机器ID)上与主机同步。

有了上述的实践,相信大家对容器也有了更多的见解。对想要进行容器化改造的企业,在这里我们也分享一下具体的改造步骤,可供参考实践:

  1. 建设组织级镜像仓库(若有Artifactory,可使用其作为Docker镜像仓库;如果没有,建议选用Harbor作为镜像仓库)。
  2. 制定镜像管理规范,确定是由哪个部门来管。
  3. 关于基础镜像、中间件镜像构建、管理及维护,要有专人负责。
  4. 制定不同语言类型的标准镜像模板及CICD工作流。
  5. 结合镜像管理规范对现有应用进行容器化改造(如一些目录调整、启停脚本编写等)。
  6. 选择合适应用进行试点。
  7. 试点阶段回顾与总结,持续反馈、持续改进。
  8. 制定全面推广策略并实施。

有了方法论,我们还需要亲自实践才能落地到实处,并在逐步实践的过程中进行迭代优化,形成最适合自己企业的研发策略。这个过程可能并不是那么容易,但是万事开头难,善用科技和工具解决一些重复性和人工易出错的问题,才能把人的时间和力量花在更有价值的地方。

0 人点赞