当我们的业务发展越来越快的时候,用户越来越多,我们对于服务的稳定性就应该要有一定的要求了,怎么保障我们的服务稳定性?根据我以前的实践,通过以下几个方面分享一下我们在服务稳定性方面的建设
- 代码质量
- 监控与告警
- 核心接口分级
- 线上故障恢复速度
- 变更管理
- 全链路压测
服务稳定性的建设是一个长期的过程,各种优化手段、工具、流程、规范都是从无到有,从有到精。我们在做稳定性建设时,可以不用一定要求一步到位,做好规划之后,按规划逐步进行即可。
代码质量
代码质量是我们在建设服务稳定性时最好入手,也是性价比最高的手段。
单元测试
单元测试是我们提升代码质量的一个简单易行的方式,对于一个对稳定性有要求的系统,每个开发应该有写单元测试的意识。
Code Review
单元测试只能验证我们代码的正确性,而代码走查,更多的是发现我们的低质量代码,以及潜在的问题点以及隐藏的性能隐患。 同时我们在对别人进行代码走查时,也是一个学习的过程。
代码走查是一个很难坚持的行为,为了更好的推进,我们一般会考虑只对hotfix、核心流程变更、影响范围较大的更变
进行代码走查。
监控与告警
监控与告警是我们提升MTTA
(问题平均响应时间)和MTTR
(问题平均修复时间)的前提,如果连这两个都没有,那么服务稳定性的的建设就是建设了个寂寞。
资源监控
资源监控一般是我们的基础设施,比如服务器资源
,硬盘、CPU、内存是否达到我们设定的阈值;或者是网络带宽
、CDN
等其它资源的监控;如果我们的业务还有对接其它的收费服务,那么费用监控
也必要的。
费用监控一般使用同比或环比来监控,是否有突然的上涨等
中间件监控
中间件监控包括我们依赖的所有中间件,比如MySQL、Redis、消息队列等等。我们除了需要重点监控它们的负载
,比如CPU、存储等之外,每个中间件也会有对应的监控内容。
MySQL
MySQL的指标很多,但是我们一般重点监控它的慢查询、当前的连接数、qps等。
Redis
Redis也类似,一般需要监控它的慢查询、大Key、qps等等。
消息队列
消息队列我们更关心它的消息堆积情况。
服务监控
服务方面我们主要监控服务的接口耗时
、qps
和服务的异常情况
等。对于服务的可用性
,一般都会通过定时请求健康检查接口来验证。
健康检查有一个比较常见的问题时,我们提供出来的健康检查接口其实检查的是我们服务是不是已经死了,它并不能检查我们的服务是不是健康,比如我的请求耗时已经超过了2秒,但是返回了成功,健康检查一般会认为服务健康,但实际上这只能说明这个服务还没死,但是它已经不健康了。
告警
我们做了这么多的监控,最终的目的都是为了帮助我们发现问题,那么当出现异常时,就需要及时的告警给对应的负责人处理。
收敛
对异常做分级和收敛,比如对于业务异常和延迟异常,我们可能只在某个时间窗口内达到了某个阈值才会认为存在异常情况。而对于非业务异常,则需要马上处理
我之前见过很多实现告警的方式,都没有收敛和分级,告警频繁,很可能造成告警疲劳,从而忽略真正需要处理的异常。
分级
对异常做分级,不同的异常使用不同的告警方式,或者升级。 比如不太重要的异常通过邮件,十分重要的异常可以通过电话告警的方式通知。
这就需要我们要建设完善的告警平台
才能够做到,前期可以先实现告警,后续再慢慢优化。
核心接口分级
接口分级,其实就是为了我们我们做熔断限流做准备,我们需要确定哪些是核心接口
,哪些是边缘接口,哪些接口挂了服务还可以提供有损服务,哪些接口挂了服务基本不受影响。只有划分了接口等级,我们才可以合理的做限流和熔断配置以及对应的降级方案。
因此我们需要
- 梳理接口,并划分等级和影响范围
- 合理的根据接口等级限流和熔断配置,并根据不同的情况提供对应的降级策略
具体的熔断限流接入这里就不多说,我们一般接入sentinel
来实现
线上故障恢复速度
当我们上面的监控什么的都做好之后,当服务出现问题时,我们可以第一时间发现,但是怎么才可以快速的恢复服务的可用?
问题排查速度
第一个是问题排查的效率,可能我们发现了异常,但是没办法第一时间找到问题所在,导致服务一直无法恢复,可能会有几个原因:
- 没有指导性的流程或规范,当出现问题时都是凭借个人经验和当时的状态,会走不少弯路
- 经验不足,毕竟线上问题出现的情况比较少
- 大家对问题排查工具的熟练度不一样
因此,我们可以通过以下几个方式去提升我们的问题排查效率:
- 部门内输出不同问题下的最佳实践,比如出现大量延迟的这种场景时,可以能过步骤A -> 步骤B -> 步骤C 即可发现大部分的延迟场景产生的原因
- 提供更高效的工具协助排查问题
- 混沌测试 + 红蓝对抗,增加我们解决问题的经验和提升能力
流程
问题没有发现不代表服务不能恢复,当出现什么影响范围的异常时需要做什么处理没有明确。这就需要我们规范化操作
,出现不同影响的异常导致服务不可用时,应该做什么,比如回滚、降级(只保留核心服务)等,这个也依赖于上面的接口分级。
没有找到问题的根因,并不代表我们无法恢复服务的可用。每个开发的习惯不一样,可能有些开发,当发现服务异常时,第一反应就是去排查问题,找根因,而不是想办法恢复服务,因此需要有流程来规范操作。
变更管理
变更包括版本发布、配置变更、DB变更
等等线上的操作,这些都有很大可能影响到服务的稳定性,因此都需要有对应的流程,或者最好通过程序来实现,比如流水线、审批流等。
我们线上出现过多次事故都是由于变更引起的,包括配置的变更,DB的变更等等,血泪教训!
全链路压测
最后,我们可以通过常态化的压测来发现我们的服务问题,特别是在可以预期到的流量高峰期前,比如大促、活动等。
稳定性衡量
通过以上手段,我们应该可以得到一个比较稳定的系统,但是我们怎么来评估我们的系统是不是稳定的? 一般业界都是通过SLA
(服务等级协议,全称:service level agreement)来衡量服务的稳定性。这个值的计算我们可以根据自己的业务场景来实现。
总结
通过以上的手段,我们正常情况下应该可以得到一个较为稳定的系统,但是服务的稳定性建设是一个持续性的工作
,不是说做完了之后就可以不管了,我们需要根据产品的发展、服务的迭代来持续的优化我们的稳定性基建,希望这篇文章对大家有所帮助。
作者:哒哒哒打代码
链接:https://juejin.cn/post/7271577604007395389
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。