一、背景
最近公司一个系统发生线上故障,系统架构为C/S的,客户端是APP;系统的功能有:联系人、短信、通话记录等,每个业务都有备份、恢复的功能,即用户可以在APP内备份自己的联系人、短信、通话记录至服务端,然后可以后续某个时间段恢复数据。
服务端架构如下:

第1层Nginx,主要做一些流量清洗、流控等处理;
第2层是应用层,分应用接入层和服务层,应用接入层做一些参数检查和登录检查等,服务层处理业务逻辑,这2层之间通过RPC通信;
底层的存储是Mysql和Hbase,Mysql存一些元数据,真正的业务数据存放在Hbase中;
该系统经过几次接手,没有人能对系统逻辑理解很清楚;
该系统从去年下半年开始一直偶尔有500的报错,但每次重启就好了,本次发生故障后,重启仍然是大量500;
二、问题分析
先查看接入层日志,发现大量的500错误:

Nginx错误日志如下:

发现是连接应用接入层超时,应该是应用接入层压力大,赶紧将接入层扩容,增加了1倍的服务器;
应用层扩容后,发现连接Hbase报错超时了(这里就不列日志了,日志很重要~)。
因为Hbase扩容后需要Rebalance,这个过程需要一段时间,为了尽量减少对线上影响,开始在nginx上限流,具体是通过access_by_lua_file指令进行限流,代码如下:
local headers = ngx.req.get_headers()local token = headers["xxx"]local tokenHashif (token == nil) or (token&nb

本文详细复盘了一次由RPC框架设计不合理导致的线上系统故障,故障表现为大量500错误及服务端处理延迟。通过对系统架构、日志分析、超时时间调整及限流策略的实施,最终解决了问题。关键在于发现RPC框架的线程池设计缺陷,即queues参数固定且无法调整,导致新请求长时间滞留。
最低0.47元/天 解锁文章
1746

被折叠的 条评论
为什么被折叠?



