2023更新,K8S中java程序OOM

故障现象:

前端web页面显示正常,但是用户无法通过任何方式登陆,报504。

检查k8s集群各node节点状态—>均为ready
检查k8s各pod状态—>均为running
检查控制台监控中各服务器的负载:
master01:正常
master02:正常

master03:CPU使用率接近100%

node01:正常
立刻登陆master03,查找CPU使用率高的原因。
在这里插入图片描述
在这里插入图片描述
发现master03上user模块占用的CPU和内存都超出正常范围,于是手动curl该模块

curl nodeip:nodeport/api/user/v1/version

返回超时

至此,用户登录504的直接原因已找到,需要立即回复业务,

在下面找出导致user模块异常的根本原因


查找user模块故障根本原因

疑点:

1、确认当时user模块占用的资源是超出正常范围的

调取日志如下在这里插入图片描述
0时区5月13日22:59(北京时间5月14日早6:59)日志记录了OOM

2、系统有剩余内存,为什么会报OOM

查阅资料得知:
因为在没有限制java容器可占用最大内存的情况下,jvm有默认值 ;
取值为容器创建时系统可用内存的25%;
所以报OOM的是user模块,因为它触到上限了,
而系统有剩余内存,则不会报OOM;

3、导致user模块占用内存过大的原因是什么?

暂时没有结论,需要开发同事帮助一起找原因。

4、为什么模块OOM了,且服务已经不可用了,容器没有因异常而退出

4.1 仅仅OOM容器是不会直接down掉的,
而如果占用的内存碰到了“硬上限”,容器才会在OOM时执行kill process
这里的“硬上限”可以是容器运行是配置的-m参数决定,也可以是系统本身的最大内存
前者的优先级高于后者
4.2我们目前用于运行jar包的容器镜像内,真正提供服务的依然是tomcat,如下图
在这里插入图片描述
请教了有经验的前辈得知
tomcat在OOM时大多数情况下不会直接退出,而是GC;这样的情形在跑多线程的程序时更加常见,
这个观点正好解释了为什么我们master03的CPU使用率很高—>因为系统忙着给user模块GC;

5、今后如何避免类似问题

可供选择的方案如下:
5.1 给容器配置JVM最大占用内存,同时也要给容器设置硬上限,只要碰到硬上限就迫使容器退出,同时依靠k8s重新拉起新的容器
5.2 在JVM中添加 如下参数,只要报oom就迫使容器退出,同时依靠k8s重新拉起新的容器;

-XX:+ExitOnOutOfMemoryError 

只要报oom就将内存快照保存

-XX:+HeapDumpOnOutOfMemoryError

保存位置

-XX:HeapDumpPath=/the/way/to/save/heapdump.hprof

5.3 打包镜像的时候加入heathcheck,

FROM yourimages:latest
HEALTHCHECK --interval=5s --timeout=2s --retries=12 \
CMD curl --silent --fail localhost:9200/_cluster/health || exit 1

–interval=<间隔>:两次健康检查的间隔,默认为 30 秒。
–timeout=<间隔>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒。
–retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
–start-period=<间隔>: 应用的启动的初始化时间,在启动过程中的健康检查失效不会计入,默认 0 秒

5.4 在user模块的yaml文件中加入存活指针的声明,

例如

apiVersion: v1
kind: Pod
metadata:
   namespace: ctg
   name: kubia-unhealthy
   labels:
      name: kubia-unhealthy
spec:
   containers:
   - image: luksa/kubia-unhealthy
     name: kubia
     livenessProbe:
       httpGet:
         path: /
         port: 8080
       initialDelaySeconds: 15 # 在k8s第一次探测前等待15s.  

delays: 延迟,delays=0s,表示在容器启动后立即开始探测
timeout: 超时,timeout=1s,表示容器必须在1s内进行响应,否则这次探测记作失败
period: 周期,period=10s,表示每10s探测一次容器
failure: 失败,failure=3,连续3次失败后重启容器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值