最近产线刚刚发布一个java应用,发布完成后,测试同学发现app调用对应的接口,比较慢或有时直接访问不了,通过抓包发现,刚刚发布的java应用,在请求对应接口是报502,根据提示初步判断是这个java应用停止了。
应用环境:
公司产线后端应用一般是部署在两个机器esc,通过公网slb做负载均衡。
client----->公网slb------->后端应用机(nginx代理)------>tomcat------>mysql(rds)
排查问题:
1.初步判断为应用停止了。
登录对应应用机,发现应用启动并没有问题(ps -ef|grep appname/more catalina.out)
2.先从公网slb检测,由于公网slb对应的后端应用不止这一对,一般产线一个slb对应4-5个后端应用,其他应用并没有出现类似问题,而且slb活跃连接数也没有达到最大限制值,所以就排除了slb出现问题的可能
3.在排查应用机了,通过uptime 、top发现这个java进程占用300%左右的cpu(产线机器都是4核8G).通过top发现cpu高的java pid。定位到具体进程了,需要定位到线程 再找到哪里的代码导致这个问题的。
通过ps -mp pid -o THREAD,tid,time,或top -H -p pid找到使用cpu高的线程
,printf “%x\n” tid 将线程id转换成16进制格式。通过jstack pid|grep tid -A 30或查看grep -C 5 "28803"catalina.out (28803是tid装换成16进制的值)日志。找到对应的信息,代码不懂就直接贴给开发同学,让开发同学优化代码。我这边是有一个每分钟会跑批导致的。我只是发现问题并找到问题。具体业务逻辑不是很清楚,直接给开发让他们优化就行。
本文并非在出现问题时来编写此文的,所以没有图片信息。主要是记录一下问题和处理方式
续集-———————
预发tomcat 启动没多久,发现1个核cpu 100%。通过jstack 找到线程"VM Thread" os_prio=0 tid=0x00007fb9d0140000 nid=0x6d35 runnable。vm线程占用大量cpu 执行 jstat pid 1000 5.
发现FGC的数据量一直递增,应该是full gc了,查看gc.log-发现大量的full gc的日志信息如下:
原因描述
通过GC日志可以看到,old区离最大配置还很远,Metaspace区并没有真正释放空间,所以怀疑是Metaspace区不够用了。
以前只认为,Metaspace区是保存在本地内存中,是没有上限的,经查阅资料才发现,原来JDK8中,XX:MaxMetaspaceSize确实是没有上限的,最大容量与机器的内存有关;但是XX:MetaspaceSize是有一个默认值的:21M。问题就出在这里
设置mataspeacesize:
使用eclipse的Mat工具来查看具体哪个对象占用内存交大