一次生产事故导致系统崩溃的原因排查过程
一次正常的生产版本迭代后,线上系统出现了资源耗尽,系统崩溃的情况,一般发生在系统运行几个小时之后,就会出现大量数据库连接无法获取,最终导致系统崩溃。
通过对数据库的排查,sql如下:
select s.SID,s.MACHINE,s.USERNAME,s.STATUS,s.LOGONTIME,s2.SQLTEXT from v$session s,v$sqlarea s2
where s.SQLID = s2.SQLID
order by s.LOGON_TIME desc
查到是一个查询卡bin信息的sql占用了大量的连接,于是,排查上次迭代版本是涉及到该语句的代码,反复的对照,通过在测试环境模拟高并发下系统的连接数变化,确定了出现连接泄露的准确位置。
出现这个重大bug的原因:系统的定时任务有统一的处理事务的方式,系统上下文是threadlocal的,所以大家在用到连接的时候,直接从context中去拿。因为业务需要,该任务中出现了线程池,查询卡bin的sql就发生在另一个线程中。于是从另外线程上下文中拿到的连接,是新的连接,但是小伙伴忽视了要自己管理这个连接,于是出现了这次生产事故。
总结:这次生产事故的产生有几个原因
1、对整个系统的连接管理理解不够。
2、对threadlocal的理解不深刻。
3、多线程运用不够熟练,没能注意并发编程中应该特别注意的问题。
评论