桔妹导读:本文给出其中稳定性相关的规范,这些规范都是顺风车成立五年来,对大量真实线上故障复盘、总结获得的,但愿对你们服务的稳定性提高有所帮助。
服务端做为顺风车技术部内最大的工程团队,随着人员的扩张和迭代,流程规范在其中扮演着原来越重要的角色。一方面规范化能够提升咱们的交付质量、交付效率,另外一方面,咱们也但愿在一次次的实战中不断的总结,探索出适用于咱们团队的最佳实践。算法
基于此,咱们制定并推广了一套适用于服务端开发的可执行、最小限制的工程规范,包括研发流程、稳定性、性能成本等多个方面。sql
本文给出其中稳定性相关的规范,这些规范都是顺风车成立五年来,对大量真实线上故障复盘、总结获得的,但愿对你们服务的稳定性提高有所帮助。数据库
下文的描述中,会用到不少的技术名词,为更容易的理解,在这里对这些名词作下简要说明:安全
本章节主要是基于大量的线上故障case,以具体实例驱动,加上研发全流程中各个环节容易犯的一些稳定性问题,提取一些反模式出来,供你们参考,尽可能避免后续的工做中犯一样的问题,提升线上服务的稳定性。网络
反模式3.1.1
过分的节点熔断策略并发
【实例】
为了提升请求成功率,在下游故障时对下游节点采起熔断措施,好比1分钟内连续出现5次访问出错,则将该节点熔断,再也不调用(过一段时间后再恢复),某天网络抖动,下游服务4个实例中的3个均进入熔断模式,致使访问下游的全部流量均落到剩余的这个实例上,压力过大,将该实例压垮。下游服务雪崩,整个系统不可用。框架
【解决方案】
熔断模式下,还须要有熔断保护措施,避免过分熔断带来的稳定性问题。运维
**反模式3.1.2
固定的重试序列**工具
【实例】
每次重试序列都为“下一台”。性能
【后果】
一个是雪崩:假设某一类 query 的重试序列为A B,当 A 出现故障时,B 要承受两倍的压力,若是 B 扛不住,那么 B 的下一个也会被压垮;一个是上线损失流量:假设重试次数是2,上线时若是 A 和 B 同时重启,那么重试序列为 A B的 query 必然无结果。
【解决方案】
评估新的重试算法,好比随机重试。不过相对于固定的重试序列,随机重试序列也可能给系统带来风险,例如可能会下降下游模块的cache命中率,下降系统性能。
**反模式3.1.3
不合理的超时设置**
【实例】
上游服务超时时间设置不合理,下游出现问题时,直接把上游服务拖垮。
【解决方案】
应该根据链路的99分位耗时来设置超时时间,同时按期对链路的通讯相关配置进行review。
**反模式3.1.4
未考虑同一请求中屡次调用下游的影响**
【实例】
服务调用下游时超时时间设置没有问题,但同一请求中会串行屡次调用某个下游服务,下游服务故障时,也会把上游服务直接拖垮。
【解决方案】
除了考虑对下游服务的单次超时,还须要考虑对下游服务的整体超时。
**反模式3.1.5
不合理的重试逻辑**
【实例】
整条链路多个地方有重试,下游服务故障时,重试被放大,致使服务雪崩。
【解决方案】
评估重试机制,梳理请求处理的整个链路,保证重试收敛在一个地方。
**反模式3.1.6
没有考虑到业务毛刺的影响**
【实例】
某业务形态有个特色,在半点和整点时刻有请求尖刺,某次受节假日影响,访问下游的流量瞬间暴增,致使下游服务雪崩。
【解决方案】
对业务尖刺进行平衡处理,减小对下游服务的峰值流量冲击。
**反模式3.1.7
没有对异常输入进行容错处理**
【实例】
业务没有对异常输入进行容错处理,仍然按照正常逻辑处理,致使数据混乱。
【解决方案】
业务特别是业务入口,必须对不合理的异常输入进行容错处理,保证整个系统的健壮性。
**反模式3.1.8
接口不支持幂等性设计**
【实例】
接口不支持幂等性,网络故障时引起大量的重试,致使核心数据大量出错。
【解决方案】
接口设计的时候就须要考虑幂等性的需求。
**反模式3.1.9
没有对非核心流程弱依赖化**
【实例】
没有对流程进行弱依赖化,致使系统总体上比较脆弱,每一个依赖单元故障都会致使整个业务瘫痪。
【解决方案】
按期对系统的流程进行梳理,最小系统化,非必须流程尽可能弱依赖化。
**反模式3.1.10
没有考虑ID溢出的影响**
【实例】
某ID使用int32,超出后ID溢出,导出服务异常。
【解决方案】
增长资源相关的ID字段时要考虑ID的范围,是否有溢出风险
按期对资源相关的ID字段进行review,提早预防,最大限度防止故障的发生
**反模式3.2.1
部署时未考虑网段因素**
【实例】
服务部署时未考虑网段因素,服务的多个实例都部署到一个交换机下,致使交换机故障时,服务的多个实例不可用,服务所在集群雪崩
【解决方案】
服务部署时尽可能多考虑地理因素,同一服务的多个实例尽量部署到不一样的机房、交换机和网段下
**反模式3.2.2
服务混部时未作好资源隔离**
【实例】
多个服务混部,其中一个CPU占用太高,致使其余服务异常
【解决方案】
多个服务混部的状况下,必定要作好资源隔离,避免因一个服务占用资源太高,致使同一台机器上的其余服务不可用
**反模式3.2.3
没有作到对核心业务和隔离和保护**
【实例】
某非核心流程因为bug向mq写入大量消息,致使整个mq集群不可用,整个业务故障
【解决方案】
核心链路和非核心链路的mq隔离,分开部署,非核心流程的变化不会影响主流程,保证核心流程和业务的稳定性
**反模式3.3.1
容量规划时未考虑故障因素**
【实例】
线上某服务qps不大,只部署了2个实例,一个实例高峰期出问题时,流量都落到另一个实例上面,把服务压垮
【解决方案】
容量估计时须要考虑容灾因素,预留必定的buffer
若是以为部署实例多,会浪费机器,能够考虑使用弹性云,比较灵活
**反模式3.3.2
上线新功能未合理进行容量规划**
【实例】
某服务,下游依赖众多,在进行容量规划时,重点都集中在某一依赖服务,未对全局全部依赖方进行全面评估,当其中某一依赖服务出现问题,致使总体服务不可用
【解决方案】
上线新功能时,须要对全部下游依赖服务进行容量规划,防止出现瓶颈点
**反模式3.4.1
代码搭车上线**
【实例】
因为缺少有效的代码修改管理机制,某产品线因为代码搭车上线,出现过屡次线上故障
而且因为变动时涉及的修改比较多,致使问题定位和追查时很是困难
【解决方案】
创建严格的代码管理机制,严禁代码搭车上线,保证任什么时候刻主干没有未上线验证的代码
**反模式3.4.2
服务回滚时遗漏回滚代码**
【实例】
上线出现问题,服务回滚后没有第一时间把代码回滚掉。次日其余同窗上线时将未回滚的问题代码再次带上线,上线时致使连续两天出现系统故障
【解决方案】
服务回滚的时候同时第一时间回滚代码
**反模式3.4.3
太高的并发部署设置**
【实例】
部署配置的并发个数过高,致使同一时刻只有少数机器可用,引起集群雪崩
【解决方案】
服务部署配置的并发个数,要保证剩余机器可以承载业务所有流量
**反模式3.4.4
服务启动或回滚时间过长**
【实例】
服务上线异常,回滚时单个服务回滚时间太长,致使未能短期内快速止损
【解决方案】
按期检查服务的启动和回滚时间,保证出现故障时能够第一时间完成回滚操做
**反模式3.4.5
配置文件缺乏有效的校验机制**
【实例】
配置文件由模型产出,数据配送系统实时配送到线上服务,模型产生的配置文件有问题,引起线上故障
【解决方案】
针对配置文件,尤为是模型产出的配置文件,创建严格的检查和校验机制
**反模式3.4.6
配置变动没有灰度**
【实例】
配置相关修改,稳定性意识上重视度不够,没有进行足够的观察和灰度,致使故障
【解决方案】
全部变动,包括服务变动、配置变动、数据变动以及环境变动,都须要进行严格的观察和灰度,保证变动的质量
**反模式3.4.7
变动没有通过严格的测试**
【实例】
变动较小,感受没有必要进行测试,结果出现低级错误,致使故障
【解决方案】
任何变动都要测试、double check,修改一行代码,也可能致使线上的稳定性故障
**反模式3.4.8
变动时没有严格按照变动规范执行**
【实例】
上线时,小流量和A机房均严格按照规范检查,服务和各类曲线没有问题,上线B机房时没有进行检查。结果B机房出现故障。
经排查是由于B机房配置缺失
【解决方案】
任何变动都要严格按照变动规范严格检查,上线的每一个阶段都要检查服务的各类曲线和指标
**反模式3.4.9
离线直接经过sql更新db数据**
【实例】
直接经过sql进行离线更新数据库,没有作好限流保护,致使db压力大,线上服务访问时出现大量超时
【解决方案】
除非特殊状况,严禁直接经过sql操做db数据,修改需经过接口修改,方便经过曲线观察,也可下降直接改库的风险;
批量修改db数据须要通报dba,通过review,确认没有问题时才能够进行操做;
批量增改、增长数据务必作好限流措施。
** 反模式3.5.1
缺乏基础监控**
【实例】
缺乏基础监控,致使出现故障,未能第一时间感知。
【解决方案】
梳理基础监控checklist,按期对服务的基础监控进行review和演练。
**反模式3.5.2
缺乏业务监控**
【实例】
缺乏业务监控,致使出现故障,未能第一时间感知。
【解决方案】
对核心流程和核心业务指标,都须要添加业务监控。
**反模式3.5.3
告警阈值设置有问题**
【实例】
因为业务bug致使线上大量告警,先临时将告警阈值从20调整到200,问题修复上线后忘了改回来,就一直维持这个阈值设置,致使后续业务出问题的时候,未能第一时间报出来。
【解决方案】
尽可能使用短暂屏蔽报警,而不是调高阈值。
**反模式3.5.4
监控告警当前已失效**
【实例】
业务迭代过快,致使监控告警信息和业务已经再也不匹配。
【解决方案】
按期对告警进行演练,保证其有效性。
重大业务迭代,须要将监控告警列入checklist。
**反模式3.6.1
上游流量异常时没有相应的防雪崩预案**
【实例】
服务上游流量突增,致使服务瞬间被压垮,系统雪崩
【解决方案】
服务必须提早作好防雪崩预案,否则很容易致使整个系统级别的故障
**反模式3.6.2
服务没有防刷和防攻击预案**
【实例】
线上问题定位时,发现某个线上服务存在大量刷接口的现象,给线上系统的稳定性带来很大隐患,同时形成很大的资源和成本浪费。
【解决方案】
线上服务,特别是和端交互比较多的服务,设计时就须要考虑好防刷和防攻击策略,提早作好预案
**反模式3.6.3
下游故障时没有相应的处理预案**
【实例】
下游服务故障,上游服务没有相应的处理预案,致使被下游拖垮,由于这种状况致使的大型故障很是多
【解决方案】
下游故障,尤为是下游弱依赖服务故障,须要有相应的处理预案
**反模式3.6.4
故障时预案已失效**
【实例】
因为业务迭代比较快,当前对某下游已经从弱依赖变成强依赖,下游故障时,执行降级预案但业务故障并无恢复
【解决方案】
按期对预案进行演练,保证预案有效性
** 反模式3.7.1
对稳定性缺少敬畏之心**
【实例】
觉得服务出故障是正常的,对稳定性不觉得然
【解决方案】
技术同窗须要对代码、线上稳定性保持敬畏之心,不能有任何侥幸心理
一行代码的bug,就可能致使整个业务瘫痪掉
**反模式3.7.2
故障时没有第一时间止损**
【实例】
服务出现故障时,相关同窗第一时间在定位故障缘由,没有第一时间进行止损
【解决方案】
出现故障必须第一优先级处理,第一时间止损
**反模式3.7.3
使用未充分验证过的技术和方案**
【实例】
某服务使用了mq的广播特性,该特性在公司尚未在线上被使用过,上线后触发mq广播消费代码中的一个bug,致使mq集群不可用的故障
【解决方案】
尽可能避免使用未充分验证过的技术和方案
若是由于某些缘由必须使用,必定要有相应的兜底措施,同时控制好接入的节奏
在非关键服务上验证充分后,才能应用到核心链路上
**反模式3.7.4
使用新技术时未控制好接入节奏**
【实例】
某服务使用了mq的广播特性,在非核心服务验证时间不够的状况下,将此特性引入核心服务,核心服务的流量比较大,触发mq广播消费代码中的一个bug,致使mq集群不可用的故障
【解决方案】
引入新技术时必定要控制好接入的节奏
在非关键服务上验证充分后,才能应用到核心链路上
**反模式3.7.5
稳定性改进方案未及时落实**
【实例】
某服务出现故障,复盘时制定了相应的改进措施,可是未及时有效落实;后该问题再次爆发,又一次服务故障。
【解决方案】
创建改进措施落实的有效跟踪机制,保证改进措施的有效落实。
顺风车服务端团队是由一群团结互助、乐观正直、追求极致的小伙伴汇聚而成,致力于构建一流的安全、交易、营销服务端技术体系,助力滴滴顺风车实现“分享出行让生活更美好”的使命 。
若是你想了解滴滴顺风车优质技术分享,欢迎关注「滴滴顺风车技术」公众号,阅读原文与更多技术干货。
欢迎关注滴滴技术公众号!
本文由博客群发一文多发等运营工具平台 OpenWrite 发布