Java项目,内存泄漏问题排查与总结,拓展容器相关知识Dockerfile

问题场景:

现象:有一次发现容器里面启动的java项目探活每过一段时间(大概半小时)就失败,导致项目在容器中重复的重启,服务时好时断。

问题描述

在容器中排查问题的时候发现了两个问题:

  1. 进入容器查看启动日志发现,项目启动之初是能够正常运行并且访问的。在经过一段时间后就出现了OOM,导致项目被hang住了,一直在进行Full GC,最终无法访问。
  2. 在这个情况下,本来想通过jstack命令去看看栈的情况,却收到提示Unable to get pid of LinuxThreads manager thread

问题2原因分析:

先分析解决第二个问题,才能更好的探查第一个问题。通过查阅资料发现,无法使用jstack命令的原因是因为,在容器启动的时候java启动命令作为容器的ENTRYPOINT而启动的,使得启动项目的进程为容器的1号进程(init进程),所以无法使用jstack查看程序的栈情况。【容器的拓展知识】

ENV OPTS=" -javaagent:/jacocoagent_skip_slb-0.8.6.jar=includes=*,output=tcpserver,port=8901,address=*,append=false -Xverify:none -javaagent:/skywalking-agent/skywalking-agent.jar -Dspring.profiles.active=test  -Dspring.application.name=passport -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"

COPY ./git-resource/target/*.jar /app.jar

ENTRYPOINT ["sh", "-c", "java $OPTS -jar /app.jar"]

问题2解决方案:

为了解决无法使用jstack的问题,只能曲线救国,不用java启动命令作为容器的启动命令。将项目启动命令放到shell脚本中,再用sh -c启动容器,这样shell脚本pid就会为1。【拓展:容器启动命令ENTRYPOINT和CMD详解】

ENV OPTS=" -javaagent:/jacocoagent_skip_slb-0.8.6.jar=includes=*,output=tcpserver,port=8901,address=*,append=false -Xverify:none -javaagent:/skywalking-agent/skywalking-agent.jar -Dspring.profiles.active=test  -Dspring.application.name=passport -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"

RUN echo 'java $OPTS -jar /app.jar' > ./entrypoint.sh

RUN chmod 777 ./entrypoint.sh

COPY ./git-resource/target/*.jar /app.jar

ENTRYPOINT ["sh", "-c", "./entrypoint.sh"]

问题1原因分析:

解决了问题2后,上容器使用jps + jstack查看栈情况发现有很多:java.lang.Thread.State: BLOCKED的线程,在等待获取锁0x00000000e1455ca0。继续往下看发现,在使用mybatis查询数据库的时候被sentinel限流拦截了。想起近期因为总部不再支持sentinel,导致查询数据库连接数一直被占用,没被释放,时间长了就使得程序oom
在这里插入图片描述

问题1解决方案:

去掉pom文件中对sentinel的引用,最后就能正常运行了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值