线上故障分析:Memorycgroupoutofmemory:。
。。
1、在某⼀天时段,我⽣产上的程序突然宕机了,部署在linux 程序被Killed掉;
使⽤ dmesg -T >my.log 命令输出到my.log⽇志,查看系统⽇志,⾄于dmesg有什么⽤,参考这篇博客:
2、根据dmesg -T的结果观察⽇志,发现如下:
查到这条信息:Memory cgroup out of memory: Kill process 7187 (java) score 1007 or sacrifice child
为什么程序会被kill掉了?原来在Linux下, 允许应⽤可以预申请内存,预申请的内存如果超过了Linux最⼤剩余内存,由于系统的保护机制,就会停掉默认内存占⽤最⼤的应⽤进程;
3、查看GC⽇志,发现⼀分钟内进⾏了3次Full GC
在哪些情况下,程序会进⾏Full GC呢,继续参考博客:
4、登录了⽣产的应⽤,发现除了宕机的其它机器上,其它机器都没有业务请求的⽇志,只有宕机的这⼀台有程序运⾏业务⽇志,是因为运维的nigix配置问题,把所有的请求都分到了宕机的这台机器上,另外的应⽤机器,虽然服务正常启动,但是没有接收到分发过来的⽤户请求;
所以我暂时把此问题理解成了运维的锅;
解决⽅案:给机器加内存,并且修改nigix配置,使⽤户请求均衡分发到每⼀台应⽤上;
5、以为问题就这样解决了,但是没有过多久,半个⽉以后,⼜发⽣了程序内存占⽤⾼,频繁报错的情况,虽然没有由于内存过⾼导致系统被Linux停掉,但很多⽤户的请求接⼝超时,⽆法正常使⽤;
先从logback中到了这样的异常⽇志:Could not get a resource from the pool#012#011at redis.clients.Resource
查看代码,之前redisPool没有设置⼤⼩,默认为8,尝试修改⼀下,修改为配置⽂件中设置的100
6、然后使⽤jstack -l pid,查看线程stack有什么异常:
发现⾥⾯有⼤量的redisson waiting(程序⾥⾯使⽤到的redis客户端)状态:
(Redisson 不仅封装了 redis ,还封装了对更多数据结构的⽀持,以及锁等功能,相⽐于Jedis 的话功能更加强⼤)
7、继续分析jstack输出的线程stack⽇志,有很多 Mysql TIMED_WAITING(先关注,这个问题在下⾯继续分析)
序错误没有通过error⽇志抛出来:
9、然后程序上线了⼀版,继续监控可能会出现的问题:
发现了mysql锁等待超时异常(也印证了上⾯第7步 jstack⽇志中,很多 Mysql TIMED_WAITING 状态的问题):
Error updating database. Cause: ptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout
exceeded; try restarting transaction#012### The error may involve
com********.dao.iface.SessionRecordMapper.updateByPrimaryKey
这⾥的异常可能之前⽇期就有发⽣过,由于上⾯第8步,之前的info⽇志输出,可能导致了忽略关注,现在才看到;
timeout of 5000ms exceeded10、分析Mysql Lock wait timeout exceeded异常:
这⾥的⼀⾏sql语句,执⾏update *** where 的时候,报错;先看⼀下这个表结构:
在表t_sys_session_rec中,sessionId是作为主键,主键是默认⾛索引的,并且在innodb引擎下,是⽀持⾏锁的;这⼀⾏数据,相同sessionId的情况,sql执⾏的并发量也不是很⼤,为什么会频繁出现等待锁超时呢?
到执⾏sql的代码,updateByPrimaryKey⽅法:
updateSession调⽤的⽅法,在/ticket校验⽅法⾥⾯,⽤户每次过来校验ticket的时候,都会调⽤这个⽅法,更新updateSession:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论