背景:
产品带着问题又来了,线上用户激活都半个小时了还没成功
拿到单号,打开kibana像往常一样想着估计又哪个地方报错了,搜了半天发现上游系统已经将消息发到MQ,但我们系统迟迟未消费消息
算了,本着用户优先的态度,先修数据吧,自己悄悄的从控制台手动重发了一个消息,成功了,,,怎么会没收到消息呢???
第一反应是MQ丢消息了,正翻看着MQ控制台,他来了,带着问题又来了,又有用户卡单了,怎么回事
发现问题:
1、单条搜日志:又是没消费消息,有点小紧张了,看了一下数据库,新单子还在往里进,嗯问题不大
2、排查影响范围:写了个sql一查,慌了,,,几千条数据、、、卡了,查了两条日志,都是没消费消息
引发问题猜想:
1、第一反应MQ挂了?立马被推翻了,如果MQ挂了,这么多系统早炸锅了
2、MQ部分服务器异常?找运维看了一下监控,一切正常
3、不是MQ服务的问题,那肯定是我们自己服务的问题了,线上数据要紧,重启后消息被消费
排查问题:
打开kibana开始搜索近一个小时的日志是否有异常,没有发现任何问题
开始按ip单台查询(线上服务器不多),问题来了其中一台服务没日志,挂了???
通过Grafana查看服务运行情况:堆内存明显飙升,gc次数瞬间暴涨
第一反应内存溢出了,运维同学查询了当时的日志,果然如此OOM
没有生成dump文件,没法分析那个类引起的
日志排查,没找到有用的日志
通过Cat查询当时的异常,慢SQL等,果然,发现了一条limit X的sql,时间对上,数据足够大,基本可以锁定是这个sql的问题了
然后通过调用链发现是产品同学通过后台导出数据时数据量过大引发OOM
反思问题:
1、触发OOM但是没有生产dump堆栈文件,排查异常麻烦(不知道Grafana能不能直接找到引发OOM是哪个类)
2、系统高频率触发OOM,开发同学无相关报警提醒
3、引发OOM后系统并未宕机,没搜到zk删除节点的日志,但为什么没有RPC流量进入了
4、MQ没有重新Rebalance队列,说明和consumer还存在心跳,但为什么不拉消息消费了
5、系统缺陷limit大数值
解决问题
1、系统缺陷
1、limit可判断最大条数,跟业务方沟通超出多大限制后直接拦截
2、生成表格类的需求是否可走大数据生成
2、MQ没有重新Rebalance队列,说明和consumer还存在心跳,但为什么不拉消息消费了,无RPC调用
1、系统活着但干不了活了,也就是假死状态,如可以ping通但ssh却连不上,这个时候心跳还在但无法处理正常请求了
2、处理方案:可在系统开发接口,直接返回true,作为服务心跳检查,可避免假死
3、回想zk的剔除服务场景(不太确定consumer节点有没有被zk剔除)
zk服务端和客户端启动成功后会建立长连接,生成会话id(Session)并设置Session超时时间,在超时时间内客户端定时向服务端发送心跳(续约超时时间)
会话期间由于外在原因可能引发连接断开或会话超时
1、连接断开:
网络抖动、客户端正常服务端宕机,客户端会重新尝试连接其他zk服务器建立连接,前提是在Session未超时的情况下
2、会话超时
客户端与服务端断开连接后,在Session有效时间内并未重新建立连接,重新连接DNS连接异常时会无法再次连接(此为低版本bug,目前3.X版本代码已修复)
总结:
1、JVM启动参数应该配置OOM时生成dump文件,方便后续堆栈分析
2、遇到类似场景应充分利用监控工具找到问题服务,第一时间考虑服务恢复(本次直接全部重启了所有服务,如果服务数量众多就不可取了)
3、自动报警不充分(可能是报警太多直接习惯性忽略了),应该有重点的报警,然后按等级分发到不同人员
4、系统健壮性欠缺(分页无最大限制),服务心跳机制不健全
公众号不定期更新各种段子、个人感悟、源码、面试题、微服务技术栈,帮忙关注一波,非常感谢