没有超时和隔离差点引发的系统雪崩

20170602公司开始618的第二天,收到了业务线订单量下滑的告警。

查看监控平台,移动端下单接口可用率掉到了99.999%,同时服务端调用次数也有一定幅度的下降。既然可用率不到100%,接口肯定有异常,遂根据关键词搜索错误日志,但是未发现有效日志数据。查看其它时间段可用率,发现并未全部是是100%,有些是由于用户的虚拟资产异常引起的可用率下降。但是其他时间段没有调用次数下降,也没有订单量下滑的告警。

订单量下滑可能是由于调用接口的次数下降引起的。从移动端同事那发现了一条有用的错误日志:“RPC框架抛出异常cause: java.util.concurrent.RejectedExecutionException: Biz thread pool of provider has bean exhausted,提示服务端线程池已满,没有空闲线程接收新的请求。”,据此确定订单量下滑的原因是客户端调用服务时,RCP框架异常,调用服务失败。但是根本原因还是在服务端。

收到服务端告警的同时,收到了一份来自DBA的慢SQL邮件,分析发现存放归档订单的数据库SQL执行超过了3分钟。经验提示我,移动端没有查询归档订单的流程。

通过归档订单数据库的标签反推,发现在一个小角落里,查询订单详情的服务可能会查询到归档订单。再次登录监控平台,通过机器维度查看监控发现确实是线上机器查到了归档订单,归档订单库本来各项配置就不高,正常情况是不会查到归档订单库的。

据此,问题尘埃落定,归档订单库执行SQL慢导致查询归档订单服务性能下降,同时引发创建订单服务的性能跟着下降,移动端调用服务异常,导致订单量下滑。

那么新的问题来了:
第一:查询归档订单和创建订单是提供给移动的两个不同的服务,为什么查询归档订单服务性能下降会影响到创建订单服务?在跟移动端沟通的同时发现,当时不仅创建订单服务抛出上述异常,几乎所有服务都抛出了以上异常。

第二:监控平台显示慢SQL执行了157秒,为什么数据库连接池没有断开?

先来看第一个问题
公司的RPC框架技术文档里写道:
分析:

  1. 提示此错误的时候,表示服务端的业务线程池已经满了。无法处理新的请求。
  2. 根本原因就是服务提供者业务代码中某个地方出现问题,导致请求阻塞,从而导致线程池耗尽。(也不一定是问题,也可能是调用量大,已经达到服务能力上限)
解决:

  1. 暂时将业务线程池大小调大,默认伸缩线程池最小20最大200;
  2. 同时线程池内部一个方法的并发大小限制暂时从默认200调大;
  3. 服务端还可以将耗时长的接口,和耗时短的接口分别指向不同的’$rpc':server(也就是指向不同端口,每个端口后面有自己独立的业务线程池,这样快接口和慢接口之间减少互相影响。)

从这里可以发现,公司的RPC框架是可以通过端口隔离每个服务的,而我们系统中使用的是最简单的默认方式(一个应用上所有的服务都是使用同一个serverId < $rpc :server id =“$rpcId" protocol =“$rpcPro" /> ),所有的服务都指向了同一个’rpc:server’,以致于该应用上所有的服务公用了同一个线程池。就出现了上述的当查询归档服务性能下降时,200个线程都去处理查询归档订单的请求 ,没有空闲的线程去处理其他服务的请求了。查询归档服务就如下图中的Dependecy I:


第二个问题:SQL执行了157秒,严重超时为什么没有断开?
检查数据库连接池配置,maxWait(获取连接时最大等待时间) \ timeBetweenEvictionRunsMillis(配置间隔多久才进行一次检测,检测需要关闭的空闲连接) \  minEvictableIdleTimeMillis (配置一个连接在池中最小生存的时间) 这些超时参数都有配置,但是唯独没有SQL执行超时的时间配置:queryTimeout(执行查询超时时间)\  transactionQueryTimeout(事务查询超时时间)validationQueryTimeout(检测查询超时时间)。关于超时相关可参靠:http://www.importnew.com/2466.html(深入理解JDBC的超时设置)

自此整个问题的来龙去脉都一目了然了。


之前做架构设计时都会考虑隔离和超时的问题,也会落地实施。如在路由流量出口项目中通过Hystrix的线程池和信号量隔离每个商家的请求,在卡密充值的项目中通过AtomicInteger原子类实现的消息限流和RingBuffer实现隔离每种任务类型。小到信号量、线程池隔离,大到每一个docker的隔离,甚至机房的隔离。在路由流量出口项目中针对每个请求包装一个超时器和熔断器,在卡密充值的项目中针对每一次外部请求都有设置一个超时器。

之前只看到过别人写的关于系统雪崩的文章,后来新的系统都未雨绸缪在设计之初都考虑到了隔离和超时引发的后果。

亲身体验一把的机会还是很难得的,在此整理总结一下:超时和隔离固然重要,运气也很重要(预发布版本迟一分钟后果不堪矣,那几个查看归档订单的用户早一刻查看亦不堪矣!)。







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值