JVM问题排查记录

CPU报警

背景:公司应用频繁cpu报警,火速开始排查。
原因:

  • 在于一个Spark Job扫描任务将待处理数据通过RocketMq发消息的方式发送到datastore应用进行处理,应用接受处理的地方还使用了线程池(Fixed),所以积压严重并且线程池打满(不指定就默认整数大小的队列),所以这里把线程池改成自定义队列长度的写法调用策略为CallerRun。
  • 刷数据经过应用存储在couchbase上,但是这里数据过大内存放不下导致一些数据落到cb磁盘,影响保存查询性能,这里暂时扩容解决。
  • 处理rocketmq的业务流程上有不合理代码编写,大量数据的嵌套遍历浪费cpu资源,在这里空间换时间用map结构优化了下,至此cpu问题告一段落。

cpu问题排查步骤:

  • jps或者ps命令;找到jvm进程号
  • top -Hp 进程号 ; 找到十进制线程号
  • printf %x 十进制线程号 ; 得到16进制线程号
  • jstack 进程号| grep 16进制进程号 -A 20 , 多次执行本步骤得到该线程在处理什么任务

服务假死

一个风和日丽的一天周日,正享受死宅的时候我们的下游服务报障了,接口偶尔延时导致请求超时,当天没管第二天上班看了下, 大部分机器正常,其中就一台机器假死了!!
nginx有健康检查好像没有转发请求到这台机器,但是我们一部分流量经过网关走到了这台机器(不知道为啥Spring cloud gateway还继续转发请求到这台机器,暂不深究吧。。)
登录到机器后查看我们的应用端口,发现大量close_wait的连接,通俗的理解close_wait就是应用一直在忙呢没空理新来的请求!! 所以快速重启这台机器解决问题!!重启万岁!!!
原因定位:
1、redis连接数过多发现一些新请求获取不到连接池资源,然后就阻塞了(这里是因为批量读没使用批量接口)。
2、打印日志、或者应用里面的一些地方使用线程池的CallerRunsPolicy拒绝策略,当任务队列满了以后,会有调用方主线程来执行导致阻塞,资源耗尽则假死。
3、机房流量不均导致。

内存报警

偶尔看到一个公司应用内存占用飙高,jmap工具能查看对象实例的数量排行,你值得拥有!然后就开始慢慢优化之路吧。

应用响应时间慢(接口慢)

实际是在排查接口为啥499超时发现这个问题的(499就是调用方请求我们接口发现超时就关闭连接了,我们的网关就出现499状态码)。
1、通过nginx访问日志,寻找499、502状态码的访问记录,然后去日志找当时的情况,然后优化!!!
2、1步骤基本能解决绝大多数的问题吧,最狠的bug就是在看nginx超时的访问记录然后对应去服务里面找当时接口的响应时间发现还都挺快的,那时间花哪去了导致超时的??
**原因就是:**JVM应用频繁发生full gc,十分钟一次的频率吓人吧。。。 这里跟我们的设计方式不好有关系,然后解决方式就是。。。现在还在想咋重构呢。。。。。。。。。。。。。

你可能感兴趣的:(java,bug排查)