最近几次生产环境出问题都是部分服务数据库连接池挂导致系统使用受影响。
首次挂是客户使用高峰期,以为是使用的人多,并发高导致连接不够就没有做深入排查,将连接池最大连接数量由50调成了100。但是后续又来了一次,这次导致影响的范围更大了,整个系统都被影响到了,开始进行查找根因。
由于系统挂了,PASS云平台自动重启导致我们拿不到dump文件和日志记录,排查变得比较棘手。首先是通过PINPONT查看那个时间段所有的请求,发现在出问题的那个时间段之前没有什么异常,请求正常,请求时间也正常,也没报错。只有在连接池满了后才出现大量异常请求,请求超时,但是这个时候应该是已经拿不到连接导致的,没分析出什么结果。
随后去看普罗米修斯的监控,发现出现问题的这段时间,数据库连接数飙升,在一分钟的时间把数据库连接打满了。但是同样的问题,由于没有第一时间去看数据库连接信息,导致具体哪个应用的连接池先满没有获取到。血的教训说明,一定要提前准备好系统挂了应该备份东西的流程,比如应用dump文件,德鲁伊监控信息,数据库连接信息,数据库进程列表processlist,有时间最好是备份一个数据库快照,方便后续找原因。
由于没有足够的信息,又一次只能靠猜。我怀疑是有什么进程再跑,能够拿到大量连接,然后连接泄露了导致这次事故。首先怀疑的就是MQ,因为前一天MQ出了问题。但是拿到MQ所有的消费和生产记录发现这个时间段也没有什么异常,吞吐量甚至还比出问题前的量还少,要出问题早就出了,又排除掉了。
后经过了解,发现我们系统的日志还采集到了Elasticsearch上,所以虽然服务器上的日志没了,但是还是有些能用的日志。但是Elasticsearch采集的日志是真的坑,又花点时间去重温下Es的查询语法,将当时的日志查出来。只能说采集日志一定要提前想好,配置好longstash,要经过分析再丢给ES,不然采集出来的日志可读性极差,查询性能也不好。但是根据这个日志也没能分析出什么东西。
几个分析下来都没有得到什么结果,就开始拖着。开始想好下次一次再出现这种问题应该具体做什么,不能因为运维压力过大就急着重启。然后想好出问题需要备份的数据等待下一次的生产事故。很快事故就又来了,说明问题没解决,这会一直出现。这次就根据之前给的开始备份所有能拿到的信息,系统的dump文件,系统日志,数据库信息。
这次拿到了系统的dump文件,那就简单了,直接用mat打开dump文件,查看连接池连接对象都被哪个进程使用。马上就发现了问题,连接池连接全部被一个url请求占用了。然后根据这个url去查相关请求信息,从日志上可以分析出来这个请求都是同一个用户发起的,而且这个sql查询还非常耗时,导致请求连接池满。后面先把这个账号封了,然后对同一IP的多次请求做限制,暂时再没出现过这个问题。