系统的稳定性建设


系统的稳定性建设

系统的稳定性建设在工作中虽然已经做了很多相关的工作,但是没有形成系统性的思考,因此通过这篇文章记录一下相关的方法论;

前言

软件系统由于自身的特点,具备横向扩展的复制能力和交付后持续迭代的特点,使得软件系统需要在不断的迭代中努力去维持系统的稳定性,不然就会导致将大量的研发资源投入到灭火中,而不是在业务的创新上,不是技术是深入上;
软件系统的稳定性建设就是保证系统在不断迭代中,能够保持稳定态,并且在发生故障时能够快速恢复到正常状态的能力;

如何衡量系统的稳定性?

在对传统系统进行稳定性判断时常用的指标是通过服务的可用时长占比,例如Uptime:999.99%,即一年中有5.26分钟的不可用时间,但是在金融系统中,由于业务的特点单纯的可用时长占比已经不能完全反映系统的稳定性了,因此需要引入数据的正确性来衡量系统的稳定性;

业务指标偏离度用于表示将实际业务数据与预期值或历史值进行比较,衡量业务指标的偏离程度。如果系统不稳定,导致数据获取或处理错误,那么业务指标偏离度可能会出现异常波动。对于金融类的系统,通常的做法是按照交易维度来进行统计的,错误的数据笔数/总的交易笔数/天或月或季,这样就能够很好的反映出系统的稳定性;

影响系统稳定性的因素有哪些?

  • 现状
    在现在的系统中,出现系统不稳定性的原因主要有一下几个方面:硬件系统导致的服务不可用、业务配置错误、代码BUG、外围服务导致等;
  1. 硬件系统导致的不可用场景:云服务厂商提供的MySQL不稳定、网络原因等
  2. 业务配置错误:产品参数开关配置错误
  3. 代码BUG:NPE、计算金额错误
  4. 外围服务导致:上游服务不按约定传参导致、下游服务不可用影响业务的正常开展

通过上面场景的分析,可以总结为下面这个图:

系统稳定性建设

影响系统的稳定性主要可以分为两个大类:自然因素人为因素;
自然因素是不能避免的原因,只能从发现、解决的环节来尽可能的降低影响;
人为因素是可以通过流程规范工具来避免的,我们在提高系统的稳定性上也是着重优化人为因素这一点;

自然因素

  1. 硬件原因
    硬件原因导致的服务不可用可以分为:
  • 服务器硬件不可用:断电、磁盘损坏、路由器不可用等等
  • 网络故障:网络超时、丢包、中断等
  1. 三方服务原因
    这里的三方服务指的是,非同一公司内部提供的服务导致不可用,通常可以分为:
  • 云服务厂商提供的服务不可用,例如存储服务、MySQL服务等
  • 开源框架的BUG

自然原因导致的系统稳定性下降,可以从两个方面进行思考:

  1. 通过冗余硬件的方式来降低风险,例如RAID技术和UPS等硬件设备;
  2. 通过事后监控的形式,尽早的发现问题,从而解决问题,控制影响范围;

人为因素

人为可以控制的因素可以划分为几个大的环节:需求评审阶段 -> 研发阶段 -> 测试阶段 -> 上线阶段 -> 故障处理

需求交付生命周期

下面从这个几个环节分析是什么原因导致稳定性降低

需求评审环节

需求评审环节指的不是对一个需求或者一个功能集(模块)的片面思考,更多是是需要从行业-公司-业务条线上的思考,没有一成不变的业务,需要运营、产品、研发一起想清楚、想透彻,然后提出合理的业务诉求,以及有预见性的业务建设;
在这个阶段有三个可以值得思考和把控的点:

  1. 团队的定位
    先抓住团队的立身之本,分析这个行业或者公司在的核心业务是什么?这个团队能为这个核心业务贡献什么?
    例如电商系统的核心部门是广告业务、金融系统的核心部门是风险或者资金部门,核心业务拥有最大的资源倾斜;
    但是核心业务在不同的时期是会发生变化的,好的职业路径肯定是不断在在核心业务条线上游走,但是很难做到;

  2. 没有长远的需求规划能力
    在实际工作中,遇到很多产品经理只是需求方的一个传话筒,这一类产品往往对行业没有一个整体的意识,只能做到被业务方牵着鼻子走,设计的方案往往也是短视的,导致的结果就是设计的产品方案是定制化的,没有横向的复制扩展能力,以及纵向业务扩展能力;

横向的复制能力指的解决的是行业内通用的痛点,通过一次方案能适用多个使用方的能力;
纵向的扩展能力指的是能对抽象出业务能力,对未来业务的变化有预见性的设计;

业务理解是对系统稳定性影响最大的一个因素,软件系统是现实需求的直观反馈,业务架构决定了技术架构;
如果产研团队对业务理解的不深刻不透彻,只能着眼于未来一年甚至几个月的短期需求和利益,想到哪里就做到哪里,那么技术层面上就无法做好提前的布局和设计,变更、堆砌、重复就会接踵而来;
万丈高楼平地起,业务需求的理解才是软件系统的地基,地基不稳定,后续在通过各种手段方法措施来进行治理都只能治标不治本;

  1. 业务需求的把控
    从业务需求层面考虑稳定型,主要从两个方面做起:一是业务需求的过滤,过滤出真正有价值的需求,二是需求模型的简化;
    对于需求价值的判断可以采用需求价值判断决策漏斗来进行分析:

需求价值判断决策漏斗

对于业务价值的判断,尤其是做创新型业务时,产品或者业务的想法很多,这能体现创新的源动力,但是作为实现这些想法的技术人员,要能从纷繁复杂的需求中找到最核心的需求,必须要对需求方的原始需求进行合理性的质疑,砍掉没有核心价值的伪需求,来精简业务模型,将有限的研发资源投入真正有业务价值的地方;

业务模型的简化会带来业务复杂度的简化,从而提高系统稳定性;

小结:对业务理解的认知,是建立全局稳定性思考的前提条件,对需求的去伪存真化繁为简决定了一个系统的复杂度,做稳定性建设必须要考虑这一环节

设计阶段

研发阶段、测试阶段、上线阶段、故障处理阶段,这几个阶段都是需要投入研发资源去进行关注的,下面依次来分析一下会导致稳定性下降的原因;

在设计阶段中主要的产出物是技术方案,表示研发阶段的开始,在这个环节中需要把控好技术设计方案的质量,从而尽量在早期进行调整;

在进行详细方案评审前,一定一定要让整个团队清楚,评审的目的是团队帮助你来检查方案,而不是挑战你的方案,不是来找茬的,有谦虚、平和的心态才能有开发、友善的建议;

  • 业务上
    在实际工作中,处理业务需求的技术方案设计遇到两类人,一类是只关心这个需求是作什么,如何才能把这个需求实现,另外一类是了解这个需求是做什么,并且知道为什么要做这个需求,并且在这个需求上进行扩展;
    第一类人,做100个需求和做10个需求的效果是一样的,没有主动思考的能力,这一类人的技术方案需要在设计评审时引导他进行思考,但是引导还是需要分人分场合进行的,工作态度严肃坚定的人和自由散漫的人提出一个相同的意见,最后得到的反馈也是不一样的;
    第二类人,能够做到主动思考,但是在主动思考过程中需要注意的是不要陷入过度设计中去,工程化实际上是围绕这效率\质量这两个点来进行的,适当才是当前最好的设计,这部分过渡设计可能更多的出现在技术上;

  • 技术上
    一个不好的技术方案,经常会出现问题的几个地方:

序号 场景 描述
1 限流 限流是服务提供者基于自身考虑提供的保护自身的能力,常见的算法有计数器算法、滑动窗口算法、令牌桶算法等,实现的框架有Resilience4j、Sentinel
2 熔断降级 熔断是防止我们的系统被下游系统拖垮,实现的框架有Resilience4j、Sentinel
3 超时机制 超时时间的设置需要遵循漏斗原则
4 重试机制 RPC框架的默认重试机制、避免出现重试风暴
5 兼容性考虑 新逻辑-兼容-老数据、老逻辑-兼容-新数据
6 隔离 数据隔离、系统隔离、读写分离、线程池隔离等

小结: 在设计阶段需要重点关注详细设计方案的技术合理性和业务合理性,两个方面;

研发阶段

这个阶段产出的是代码,对于代码codeReview是最后一个流程,在这个动作中,可以有三个需要关注的:

  1. 技术经理统一代码风格
  2. 结对编程,这里的结对编程不是说一个人写,一个人在旁边看,而是一个人负责写,另外一个owner负责codeReview
  3. 单元测试的覆盖度,单元测试一定是必要的!在提测前发现问题,影响越小;

在这个阶段中,遇到最多的问题是写代码的同学对边界值、API不熟悉、代码混乱等,没有降低整体复杂度的意识;

测试阶段

在测试阶段,容易忽略的是正常场景的回归;测试需要做到全流程全场景的覆盖,通过人工手动的去完成,是一个低效不稳定的方法;
测试的原则是尽可能的用机器完成自动化测试和全场景的覆盖,将宝贵的人力资源投入到必须用人力进行测试的环节

上线阶段

在上线需要关注的是两点:代码和配置

  1. 代码
    如果代码没上去,一切都是白搭,检查上线的内容
  2. 配置
    对应的业务配置也需要调整

故障处理阶段

故障处理阶段需要注意处理问题的先后顺序,原则上是按照下面这个流程进行处理

故障处理流程.png

第一点需要注意的是和业务方的沟通以及在问题发现时及时团队内同步;
第二点需要注意的是一定要正确定位到问题在进行修改,避免产生连锁问题;

应对措施

上述阐述了影响系统稳定性的几个原因,针对这些原因可以从以下几个方面来进行应对;

制度/规范

制度或者规范要能去落地才是好的制度,必须是要符合人的本性的;按研发流程划分主要分下图:
制度规范
在这几个环节过程中都会产生问题,但是问题的影响范围从大到小,解决问题消耗的资源从小到大;举一个例子,在需求评审阶段如果对于需求的理解出现偏差会导致返工,由于返工压缩工期又会增加系统的不稳定性;

工具

工具

工具可以为我们降低稳定性建设的资源投入,提高效率,主要分为研发工具故障排查工具

预案

预案

出现问题是无法避免的,但是解决问题的方式方法是有一定的流程的,通常出现的问题是线上出现问题,在没有保存现场时,直接重启,导致无法找到故障原因、第二种是处理问题的顺序错误,应该先降低影响,在探寻原因;

总结

一个简单的总结就是:

  1. 做好需求的分析和设计
  2. 做好技术方案的评审
  3. codereview以及单元测试
  4. 测试场景的覆盖
  5. 故障应对预案

其实最后还应该有一个复盘阶段,但是个人在实际工作中感觉复盘是一项意义比较小的工作,有些坑还是要亲自跌倒了才能长记性;

参考资料

阿里浅谈系统实现层面稳定性保障
万字长文浅谈系统稳定性建设
稳定性全系列(一):如何做好系统稳定性建设
换个角度聊系统稳定性建设


  TOC