持续集成选型和发布模式

持续集成-选型和发布模式

代码的生命周期

  1. 产生需求: 涉及到需求管理
  2. 开发人员编码: 涉及到代码仓库, 多人协作等
  3. 代码测试: 一般只是简单的基础校验; 如语法规范, 注释格式, 提交信息, 依赖验证, 单元测试等;
  4. 打包: 产出交付物
  5. 测试环境验证: 功能测试,性能测试, 灰度测试等
  6. 生产环境部署: 可能会回滚

需要考虑的几个组件

  1. 代码仓库
  2. 代码编译
  3. 包管理
  4. 测试
  5. 部署管理

代码仓库

如果没有特殊需要, 一般也都是 git 管理了, git 的仓库可以考虑这几个

优点 缺点
github 不需要介绍 国内访问存在不确定性
gitee 就是国内访问质量好 缺点就是可信度不高
gogs 如果只是单纯的 git 仓库, 这个就行了,轻量简单 功能单一
gitlab 可以私有化部署, 企业集成度比较高, 功能丰富 太重, 集成了太多杂乱的组件, 复杂
gitea 强烈推荐, 既轻量,又功能丰富 没有明显感觉
onedev 最近刚发现,感觉很不错,国产项目,似乎可以平替gitlab 未知

CI

Continuous Integration 持续集成, 目的快速输出交付物。

频繁地将代码集成到主干的优点

  1. 小功能尽快合并, 可以快速发现错误
  2. 避免大版本更新合并困难;

需要的能力

  1. 自动代码合并, 不同的环境到不同的分支;
  2. 自动构建
  3. 测试: 单页测试和一些规范的验证。

CI工具非常多, 但一般主要考虑这几款

产品 介绍
github-actions 如果代码是在 github 上,当然是首选了;
有一定免费额度可以用, 小项目足够了
gitlib-ci 如果代码是在 gitlib 上,当然也是首选了
gitea-runner 如果代码在 gitea 上也是首选, 基本兼容 github-actions 的语法和插件。
但是这个项目的问题就是太新了,gitea 1.19 才开始正式支持, 也就是才发布几个月。
目前来说, 勉强可以用, 但稍微特殊一点的功能就不大能支持;
个人其实不大看好未来发展,因为开发进度的人员数量似乎有些不足,现在的进度也慢。
jenkins 老牌集成工具
drone 主力推荐, 轻量级,插件都是容器化方式,定制功能非常方便。
虽然是开源的, 但也需要注意一点商业许可问题,轻量使用是免费的
Woodpecker 因为 drone 的诡异的商业许可问题, 所以出现了开源平替。
基本兼容 drone, 推荐,个人非常看好

还有一些云厂商的, 比如阿里的云效等, 没用过,但如果深度使用他们平台的话,应该也是挺不错的。

一般简化流程

  1. 提交代码到功能功能分支
  2. 单元测试和代码评审或验证
  3. 合并到dev分支
  4. 自动发布测试环境验证, 压力测试, 集成测试等
  5. 合并main分支
  6. 发布生产环境

语义化版本

简单理解就是友好的版本号

通过 git commit 时标识信息来确认这次发布的类型,引导相应动作。

生成的版本号规则

  • 主版本号: 当你做了不兼容的 API 修改
  • 次版本号: 当你做了向下兼容的功能性新增
  • 修订号: 当你做了向下兼容的问题修正

commit语义

commit 附带的 Message 格式遵守一定规范语法

  1. 方便工具解析和自动化流程
  2. 方便生成 ChangeLog 等
  3. 工具自动生成版本号

Commit 所遵守的规范称为约定式提交(Conventional Commits)

语义化发布首先将 Commit 进行分类, 常用的分类(Type)有:

标识 说明
feat: 新功能, 增加次版本号
fix: BUG 修复, 增加修订号版本号
docs: 文档变更
style: 文字格式修改
refactor: 代码重构
perf: 性能改进, 增加修订号版本号
test: 测试代码
chore: 工具自动生成

CD

Continuous delivery 持续交付

频繁地将软件的新版本, 交付给质量团队或者用户, 以供评审, 即快速进入测试环境验证;

Continuous Deployment 持续部署

目的是快速将交付物发布到生产环境中, 并验证新版本能否运行正常。

需要的能力

  1. 快速发布能力: 并行发布, 预推送等
  2. 快速验证能力:自动化实际业务测试能力
  3. 快速回退能力:通过备份、环境变量、软链接、重发或回退版本、切换流量等方式

常规工具栈

  1. 最早就是脚本推送重启了
  2. 然后就是 ansible 这一类集中管理工具
  3. 再然后就是 k8s 集群这类平台化容器管理方式
  4. 目前比较看好和推荐 Argo 来做 持续部署
  5. 云厂商自有的体系
  6. Terraform 基础设施

k8s集群环境工具栈

  • k8s内有状态基础组件: k8s Operator
  • 频繁变更的无状态业务应用: ArgoCD
  • 不经常变更的外部组件: helm
  • 临时性任务或开发中的新应用: yaml
  • 多环境的区分部署: Kustomize, helm

云厂商工具栈

包管理

以前有过的方式

  1. 交付 war,jar, tar.gz 等形式的包文件,找一个文件目录或ftp进行存放
  2. 研发推送到统一的包仓库,如 npm 仓库, yum 仓库, mavn 仓库,pipy 等等
  3. 提交一个 release 到 github 或 gitea 或 gitlib 中

推荐的方式
如果不是最终交付的成品, 如果依赖库这种, 建议就是语言自身的私服中和 git release 两种方式组合管理

如果是最终交付物, 还是推荐 git release 方式和 ftp 类进行管理

发布模式

重建部署

版本A下线后版本B上线

重建策略是一个冗余的方式,它包含下线版本A,然后部署版本B;
服务的停机时间依赖于应用下线和启动耗时

优点:便于设置, 应用状态完整更新
缺点:对用户影响很大,预期的宕机时间取决于下线时间和应用启动耗时

滚动部署

又称 滚动更新或者增量发布

例如服务池有10个实例,

  1. 先增加2个新版本实例,
  2. 接收流量并且健康检查通过后;
  3. 下线旧版本 2 个实例;
  4. 循环上述过程直到全部更新。

相关参数

  1. 并行数,最大批量执行数:同时发布新实例的数目;
  2. 最大峰值:考虑到新增的实例数,即最大新旧副本数;
  3. 最大不可用数:在滚动更新过程中不可用的实例数;
  4. 最小可用数: 最少N个副本需要是正常的,才能进行下一轮次发布;

优点:

  • 便于设置
  • 版本在实例间缓慢发布
  • 对于能够处理数据重平衡的有状态应用非常方便

缺点:

  • 发布/回滚耗时
  • 支持多个API很困难, 即 API 兼容性保障难
  • 无法控制流量

蓝绿/部署

又名 红/黑

两种模式

  1. 日常情况下,环境由2个副本池运行,蓝绿各承担50%流量,蓝绿之间不存在互相调用;
  2. 日常只有1个区域, 旧区域下线时直接删除,新区域上线前创建。

发布过程

  1. 先将某一区的流量比例调整为0%
  2. 更新此区域的副本
  3. 调整新区的分流比例从 1%至5%进行验证,如果正常则提升至100% (旧区域减至0);
  4. 验证完全正常后,升级旧区域的应用版本;
  5. 最后流量再调整回各50%

如果升级失败则切换回旧副本。

优点:

  • 可以提前内部或小范围验证新环境, 实时发布、回滚,
  • 避免版本冲突问题,整个应用状态统一一次切换
  • 有一个单元总是可用的,回滚快速;

缺点:

  • 资源翻倍
  • 在发布版本到生产环境之前,整个平台的主流程测试必须执行
  • 处理有状态的应用很棘手

金丝雀部署

新版本向一小部分用户发布,验证后再完全放开。

通常流量是按比例分配的; 例如90%的请求流向版本A,10%的流向版本B;

用于缺少足够测试,或者缺少可靠测试,或者对新版本的稳定性缺乏信心的情况下。

优点:

  • 版本面向一部分用户发布
  • 方便错误评估和性能监控
  • 快速回滚

缺点:

  • 发布缓慢

A/B部署

与 金丝雀部署 模式类型,差别是 只将 符合特定条件的流量给到新版本。

用于测试特定功能的切换,并发布使用占大部分的版本

例如

  • 根据用户uid
  • 地理位置
  • 设备类型, 语言等

优点:

  • 多个版本并行运行;
  • 方便提前获得客户反馈,减少致命的影响和低级的错误;
  • 完全控制流量分布;

缺点:

  • 需要智能负载均衡网关和更高的自动化发布程度。
  • 对于给定的会话,很难定位问题,分布式跟踪是必须的

影子部署

即流量镜像模式

新版本B接受真实的业务流量请求,但是不产生响应;
例如大部分的查询类业务操作, 如果有写操作需要mork;

配置非常复杂,而且需要特殊条件,尤其是分出请求

优点:

  • 可以使用生产环境流量进行性能测试
  • 对用户无影响
  • 直到应用的稳定性和性能满足需求后才发布

缺点:

  • 双倍资源,成本昂贵
  • 配置复杂
  • 对于需要变更数据的业务操作要么关闭,要么定制操作;
  • 不是真实用户测试,可能出现误导
Licensed under CC BY-NC-SA 4.0
转载或引用本文时请遵守许可协议,知会作者并注明出处
不得用于商业用途!