简介
"稳定性"一词主要指的是软件系统在外界影响下能够保持正常运行的能力,常用服务的可用时长来衡量(常见的四个九指服务一整年的不可用时间不超过52分钟)。外界影响也可看做故障源,主要分为两类:一类是人为变更,还有一类是意外影响。稳定性治理的目标是提前发现并消除故障源(故障前)、降低故障的影响范围(故障中)和建立故障的负向反馈机制。
事前预防
只有明确具体的故障源,才能针对性地治理。大部分故障都是变更导致的。一个软件上线的过程包含以下变更:代码变更、网关变更、动态开关变更、限流降级配置变更、路由规则变更、数据库变更等,其中代码变更和数据库变更非常频繁,因此是治理的重点。
代码变更
完善的代码变更流程可以增大故障的暴露概率,提前发现问题,预防出现线上问题。 代码变更上线往往需要经过以下流程:产品需求内审(产品内部)、产品需求评审、DevDesign评审、测试用例评审、代码开发、代码自测、联调、code Review、线下测试、beta测试、线上灰度、全量。
- DevDesign:要明确业务和系统价值,阐述系统设计和详细变更,必要时候还要确定是否影响核心链路、是否是不兼容的变更(这一部分公司一般会搞一份模版)。参会人员往往包含关联开发、组内开发以及TO,比较复杂的更会上升到技术委员会这类的组织
- 代码开发:主要是遵循各种规范,基础的规范都有插件会识别
- 代码自测:完成测试的用例,并编写完备单元测试。复杂的测试数据或者场景,可以让测试准备好,这个能省不少时间,提高效率
- CR: cr往往需要超过1个人的AC,才能提交。reviewer除了检查通用规范,还需要准备业务自定义的检查细节。CR还可以设置其余卡点规则,例如单测覆盖率、是否新增测试用例、自动化测试、规范扫描、各种包版本黑名单检查。CR的响应效率也很重要,可以设置各种机器人定期提醒reviewer及时响应。
数据库变更
数据库变更主要是double check,组内同学或者TO和DBA双重检查,通过后才能手动执行或者自动执行。
故障中
故障中侧重于尽可能地发现故障,并及时响应,正确地处理故障(消灭或者降低)。
- 熟悉常见的操作:回滚、隔离、扩容
- 定期梳理业务流程,完善监控指标,并建立系统性的警报系统
- 灰度发布阶段需要完善观测机制,必要的观测行为需要double check,通过后才能流转到下一个阶段
- 建立预案,并定期演练,熟悉操作。
故障后
大一点的故障则每次都要复盘,很小的故障可以定期批量复盘。需要产出复盘文档,包含改进的Action,并检查执行进度。
实践
- 梳理业务核心流程、服务高QPS请求和高耗时接口
- 核心业务流程包含rpc调用、存储和缓存使用
- 高QPS接口可以选取top N的接口分析
- 高耗时接口可以选择耗时高于某个阈值(自定义评估,每个业务都可能不一样)的接口
- 核心业务与非核心业务隔离(服务化或者系统资源隔离)
- 完善监控指标(数据库、消息队列、缓存、系统指标(rt\CPU\QPS\disk\Io\mem\gc\thread)、业务自定义监控),制作监控大盘
- 流量治理或者高耗时接口治理(泡沫流量治理、接口放大治理、鉴权治理、高耗时治理)
- 完善限流降级熔断机制
- 核心链路上非强依赖rpc调用/存储做好熔断,强依赖做好降级
- 高QPS接口做好限流和降级,针对个人免费用户和收费用户制定不同的降级策略
- 容量规划
uv = w * MAX_QPS
MAX_QPS = u * MIN_POD_NUM
MAX_QPS = v * MAX_POD_NUM
更加上述公式以及一年内最大uv以及当天的峰值QPS(MAX_QPS),分别计算出u,v,w系数,再更加uv的增长百分比,计算出新一年的最大的uv,以及最大的容量规划
- 预案和演练
总结
稳定性是一项长期投入的工作,投入的成本也是很大的,因此需要针对自己的业务稳定性短板选择可承受成本下的措施。