跳转至

9 持续交付理论总结及面试

1 量身定制你的持续交付体系

虽然持续交付着重打造的是发布流水线的部分,但它所要达到的目标是在“最终用户”和“研发团队”之间建立紧密的反馈环:通过持续交付新的软件版本,以验证新想法和软件改动的正确性,并衡量这些改动对软件价值的影响

2 配置管理

代码分支策略的选择

  • 主干开发(TBD)
  • GitHub Flow 是 GitHub 所使用的一种简单流程。该流程只使用 master 和特性分支,并借助 GitHub 的 pull request 功能。

依赖管理

Maven 使用 XML 格式的文件进行依赖配置描述的方式,叫作 POM(Project Object Model ),以下就是一段简单的 pom.xml 文件片段

在 POM 中,根元素 project 下的 dependencies 可以包含一个或多个 dependency 元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:

groupId、artifactId、version: 依赖的基本坐标; / type: 依赖的类型,默认为 jar;/ scope: 依赖的范围;/ optional: 标记依赖是否可选; / exclusions: 用来排除传递性依赖;

代码回滚

  • 第一种情况:开发人员独立使用的分支上,如果最近产生的 commit 都没有价值,应该废弃掉,此时就需要把代码回滚到以前的版本。
  • 第二种情况:代码集成到团队的集成分支且尚未发布,但在后续测试中发现这部分代码有问题,且一时半会儿解决不掉,为了不把问题传递给下次的集成,此时就需要把有问题的代码从集成分支中回滚掉
  • 第三种情况:代码已经发布到线上,线上包回滚后发现是新上线的代码引起的问题,且需要一段时间修复,此时又有其他功能需要上线,那么主干分支必须把代码回滚到产品包 V0529 对应的 commit。

代码回滚必须遵循的原则

  • 集成分支上的代码回滚坚决不用 reset --hard 的方式,

三种典型回滚场景及回滚策略

  • 个人分支回滚
  • 集成分支上线前回滚 revert before merge request
  • 集成分支上线后回滚
$ git fetch origin  
$ git checkout master
$ git reset --hard  V0529         # 把本地的 master 分支的指针回退到 V0529,此时暂存区 (index) 里就指向 V0529 里的内容了。
$ git reset --soft  origin/master  # --soft 使得本地的 master 分支的指针重新回到 V05javascript:;30,而暂存区 (index) 变成 V0529 的内容。
$ git commit -m "rollback to V0529"  # 把暂存区里的内容提交,这样一来新生成的 commit 的内容和 V0529 相同。 
$ git push origin  master        # 远端的 master 也被回滚。

3 环境管理

发环境,功能测试环境,验收测试环境,预发布环境,生产环境这五个大套环境。

了解各种配置方法

  • 构建时配置

以 Maven 为例,实现多环境的构建可移植性需要使用 profile。

profile 是一组可选的配置,可以用来设置或者覆盖配置默认值。通过不同的环境激活不同的 profile,可以实现构建的可移植性。

maven initialize –Pdev   &  maven initialize –Pprod
  • 打包时配置
  • 运行时配置

4 构建集成

构建的提速

  • 级硬件资源
  • 搭建私有仓库
  • 使用本地缓存
  • 规范构建流程
    • 以 Java 构建为例,Enforcer 检查、框架依赖检查、Sonar 检查、单元测试、集成测试这些步骤,并没有放在同一个构建过程中同步执行,而是通过异步的方式穿插在 CI/CD 当中,甚至可以在构建过程之外执行。
  • 善用构建工具
    • 以 Maven 为例
      • 设置合适的堆内存参数
      • 使用 -Dmaven.test.skip = true 跳过单元测试。
      • 在发布阶段,不使用 Snapshot 版本的依赖
      • 使用 -T 2C 命令进行并行构建
      • 局部 / 正确使用 clean 参数

构建检测

  • Maven Enforcer 插件提供了非常多的通用检查规则,比如检查 JDK 版本、检查 Maven 版本、检查依赖版本,等等

5 发布及监控

发布

因此,我们想要的应该是:一个易用、快速、稳定、容错力强,必要时有能力迅速回滚的发布系统

  • 扩展到集群

灰度发布是指,渐进式地更新每台机器运行的版本,一段时期内集群内运行着多个不同的版本,同一个 API 在不同机器上返回的结果很可能不同

  • 蓝绿发布: 是先增加一套新的集群,发布新版本到这批新机器,并进行验证,新版本服务器并不接入外部流量
  • 滚动发布: 是不添加新机器,从同样的集群服务器中挑选一批,停止上面的服务,并更新为新版本,进行验证,验证完毕后接入流量。
    • 重复此步骤,一批一批地更新集群内的所有机器,直到遍历完所有机器\
  • 金丝雀发布: 从集群中挑选特定服务器或一小批符合要求的特征用户,对其进行版本更新及验证,随后逐步更新剩余服务器。

发布系统的用户体验

1 张页面展示发布信息: 发布中 / 未发布时

6 大页面主要内容

集群 / 实例 / 发布日志 / 发布历史 / 发布批次 / 发布操作。

发布系统的核心架构和功能设计

发布系统的核心模型主要包括 Group、DeploymentConfig、Deployment、DeploymentBatch,和 DeploymentTarget 这 5 项。

  • Group 的属性非常重要,包括 Site 站点、Path 虚拟路径、docBase 物理路径、Port 应用端口、HealthCheckUrl 健康检测地址等,这些属性都与部署逻辑息息相关。
  • DeploymentConfig,即发布配置,提供给用户的可修改配置项要通俗易懂
  • Deployment,即一个发布实体,主要包括 Group 集群、DeploymentConfig 发布配置、Package 发布包、发布时间、批次、状态等等信息。
  • DeploymentBatch,即发布批次

如何利用监控保障发布质量

  • 用户侧监控,关注的是用户真正感受到的访问速度和结果;
    • 端到端的监控 / 唯一用户 ID 的监控
  • 网络监控,即 CDN 与核心网络的监控;
    • 公网监控 / 内网监控
  • 业务监控,关注的是核心业务指标的波动;
  • 应用监控,即服务调用链的监控;
    • 调用链监控系统,一般采用在框架层面统一定义的方式,以做到数据采集对业务开发透明,但同时也需要允许开发人员自定义埋点监控某些代码片段
  • 系统监控,即基础设施、虚拟机及操作系统的监控。
    • 系统监控,指的是对基础设施的监控。我们通常会收集 CPU、内存、I/O、磁盘、网络连接等作为监控指标

6 测试管理

代码静态检查实践

代码静态检查; / 破坏性测试; / Mock 与回放

  • SonarQube 采用的是 B/S 架构,通过插件形式,可以支持对 Java、C、C++、JavaScript 等二十几种编程语言的代码质量管理与检测。

如何提高静态检查的效率?

  • 其一,能够缩短代码扫描所消耗的时间,从而提升整个持续交付过程的效率;
  • 其二,我们通常会采用异步的方式进行静态检查,如果这个过程耗时特别长的话,会让用户产生困惑,从而质疑执行静态检查的必要性。

破坏性测试

  • 第一,破坏性测试的手段和过程,并不是无的放矢,它们是被严格设计和执行的
  • 第二,破坏性测试,会产生切实的破坏作用,你需要权衡破坏的量和度

因此,绝大部分破坏性测试都会在单元测试、功能测试阶段执行。而执行测试的环境也往往是局部的测试子环境。

混沌工程: chaos monkey

Mock与回放技术助力自动化回归

Mock 因为这样的模拟能力,为测试和持续交付带来的价值,可以总结为以下三点:

使测试用例更独立、更解耦 / 提升测试用例的执行速度 / 提高测试用例准备的效率

  • 基于对象和类的 Mock: Mockito 或者 EasyMock 这两个框架的实现原理
  • 基于微服务的 Mock: Weir Mock 和 Mock Server。这两个框架,都可以很好地模拟 API、http 形式的对象。

7 持续交付平台化

  • 代码管理模块,往往会和代码审核、静态扫描和分支管理等模块相联系;
  • 集成编译模块,也会与依赖管理、单元测试、加密打包等模块相生相随的
  • 环境管理模块,离不开配置管理、路由管理等模块
  • 发布部署模块,还需要监控模块和流控模块的支持