前言
# 01.项目流程
# 02.互联网产品生命周期
# 03.大规模微服务集群的典型架构
# 04. go进阶学习路线
# 05. 项目开发流程与规范
# 5.1 开发阶段
Git 与工作流,Git 的特性催生了基于 Git 的多种工作流模式,包括:
- 集中式工作流
- Git Flow 工作流
- GitHub Flow 工作流
- GitLab Flow 工作流
目前大型项目用得比较多的 Gitflow 工作流 和 GitHub Flow 工作流。
Gitflow 工作流(Gitflow Workflow)是 2010 年 Vincent Driessen 在他的一篇博客 (opens new window)里提出来的。它定义了一套完善的基于 Git 分支模型的框架。
Gitflow 工作流 结合了版本发布的研发流程,适合管理具有固定发布周期的大型项目。它对于分支的定义有下面几点:
- Master 分支:作为唯一一个正式对外发布的分支,是所有分支里最稳定的。
- Develop 分支:是根据 Master 分支创建出来的。Develop 分支作为一种集成分支 (Integration Branch),专门用来集成已经开发完的各种特性。
- Feature 分支:根据 Develop 分支创建出来。Gitflow 工作流里的每个新特性都有自己的 Feature 分支。当特性开发结束以后,这些分支上的工作会被合并到 Develop 分支。
- Release 分支:当积累了足够多的已完成特性,或者预定的系统发布周期临近的时候,我们就会从 Develop 分支创建出一个 Release 分支,专门做和当前版本发布有关的工作。Release 分支一旦创建,就不允许再有新的特性被加入到这个分支了,只有修复 Bug 或者编辑文档之类的工作才能够进入该分支。Release 分支上的内容最终会被合并到 Master 分支。
- Hotfix 分支:直接根据 Master 分支创建,目的是给运行在生产环境中的系统快速提供补丁。当 Hotfix 分支上的工作完成以后,可以合并到 Master 分支、Develop 分支以及当前的 Release 分支。如果有版本的更新,也可以为 Master 分支打上相应的 Tag。
Gitflow 工作流诞生于 2010 年,在这 10 年间软件开发的模式发生了很大变化,敏捷开发通过持续迭代的方式,让产品发布不再具有固定的发布周期。因此,Gitflow 工作流虽然很有名,但它不是灵丹妙药,也不适用于所有场景。而更适合敏捷开发且流程更简单的 GitHub Flow 工作流逐渐变为了主流。
在 GitHub Flow 工作流中,通常有一个管理者维护的主仓库。一般开发者无法直接提交代码到主仓库,但是可以为主仓库代码提交变更。在通过了自动化 CI 校验和代码评审(Code Review)之后,维护者会将代码合并到主分支中。
GitHub Flow 工作流的详细过程如下:
- 项目维护者将代码推送到主仓库。
- 开发者克隆(Fork)此仓库,做出修改。
- 开发者将修改后的临时代码分支推送到自己的公开仓库。
- 开发者创建一个合并请求(Pull Request),包含进行本次更改有关的信息(例如目标仓库、目标分支、关联要修复的 issue 问题),以便维护者进行代码评审。
- RP 通过后,临时代码分支将被合并到指定的分支,合并前可能有一些需要解决的代码冲突。合并完成后,GitHub 在合并分支的 commit 记录中可以连接到之前 PR 的页面,帮助我们了解更改的历史、背景和评论。
- 合并拉取请求后,维护者可以删除临时代码分支。这表明该分支上的工作已经完成,同时也可以防止其他人意外使用旧分支。
# 5.2 测试阶段
测试可分为六类:
- 代码规范测试:包括对代码风格、命名等的检测,主要工具有 gofmt、goimport、golangci-lint 等。
- 代码质量测试:包括代码的覆盖率。主要工具有 go tool cover 等。
- 代码逻辑测试:包括并发错误测试、新增功能测试。主要工具有 race、单元测试等。
- 性能测试:包括 Benchmark 测试、性能对比。主要工具有 Benchmark、ab、pprof、trace 等。
- 服务测试:测试服务接口的功能与准确性,以及服务的可用性测试。
- 系统测试:包括端到端测试,确保上下游接口与参数传递的准确性、确保产品功能符合预期。
# 5.3 上线阶段
上线部署过程中需要遵循如下流程:
上线避开高峰期上线,尽量不要在节假日之前上线变更较大的版本,不在业务量大的时期做任何变更操作。
提前通报利益相关者,例如项目组成员、组内成员、有影响的上下游。
严格规范上线执行步骤、确定检查清单与回滚方案。
灰度发布,并且对于要变更的功能,采取逐步放量的方式。例如只放量 A 城市 M 品类 30% 的流量,这样 A 城市 M 品类 30% 的用户才会体验到新功能,最大限度地减少变更时候的风险。借助灰度发布也能进行 A/B 实验,这样可以观察不同策略下用户的行为,从而做出科学的决策。
分级发布,遵循先少量,再部分,最后全量的原则;严格控制每一次部署的时间间隔。通常大公司还有接近线上环境的预发环境,首先在预发环境中部署服务并验证服务的检查清单。对于核心服务来说,上千个容器是很常见的事情,分级发布有助于减少问题出现时的影响面,因为大部分问题都是服务的变更引起的。
另外,在上线时进行检查,观察当前服务指标是否异常,如发现异常应尽快回滚,止损后再查明问题原因。部署过程中,需要观察程序的核心指标,包括系统指标(上下游调用错误率、接口的平均响应时间和 P99 响应时间、CPU、内存、磁盘的利用率等)和业务指标(服务错误率、核心接口请求量等)。以打车业务为例,监控的指标包括:是否出现天价账单、特定费用项(如时长费、动态调节费)是否出现大的波动,平台是否抽成过高等问题。
最后,在上线过程中还要及时关注报警群,关注上下游的反馈,收集错误日志,并抓取 case 查看。
服务部署完成后,一些重要变更还需要 QA 工程师进行回归测试,验证服务在线上是否符合预期。
# 5.4 运维阶段
SRE 工程师通常是围绕着缩减下面的几个时间来提高整个系统的稳定性水平:
- MTTI (Mean Time To ldentify)平均故障发现时间
- MTTA(Mean Time To Acknowledge)平均故障确认时间
- MTTL (Mean Time To Location)平均故障定位时间
- MTTT (Mean Time To Troubleshooting)平均故障解决时间
- MTTV (Mean Time To Verify)平均故障验证时间
而要确定服务是否稳定运行,需要对目标进行量化。所有运维的工作都围绕着 SLO(服务水平目标)的定制、执行、跟踪和反馈来展开。
Google 提出了下面这套 VALET 法帮助我们定制自己的 SLO 指标,包括了如下几个因素:
- Volume(容量):服务承诺的最大容量。比如常见的 QPS、TPS、会话数、吞吐量以及活动连接数等等。
- Availablity(可用性):服务是否正常 / 稳定。比如请求调用 HTTP 200 状态的成功率,任务执行成功率等。
- Latency(时延):服务响应速度。有时我们需要判断时延是否符合正态分布,或者指定不同的区间,比如常见的 P90、P95、P99 等。
- Error(错误率):服务错误率,比如 5XX、4XX,以及自定义的状态码。
- Ticket(人工干预):服务是否需要人工干预,面对一些复杂的故障场景,就需要人工介入来恢复服务。