1、背景
因为 Oracle 对外声称 Oracle JDK 进行收费用于商用。公司法务部门评估之后放心后续会惹上光司,于是就开始了 JDK 降级 - 将所有服务 Oracle 批改为 OpenJDK。上周开始微服务 JDK 降级本来只不过是一个根底组件的降级,因为没有波及业务代码的变更感觉问题不大。但怎么也想不到开始降级之后便陆陆续续呈现服务一直重启的异样设想。这到底是咋了?
2、问题裸露
降级镜像之后,java 服务频繁重启,服务对外的接口处于半不可用状态,具体表现为接口申请失败率 5 -10%(该接口对应数据看板次要是内部人员应用,之所以没有第一工夫进行止损)
3、异样排查
本次降级除了更新根底 JDK 镜像,既没有业务代码的变更也没有批改配置,到底是什么起因导致的呢?
带着非常困惑的情绪,我和团队开启了漫长的异样排查之旅。
1)过后呈现服务重启,第一感觉是启动耗时长导致探测接口超时超过肯定阈值导致重启。
于是在产生异样重启的第 1 个小时内,我把探测超时由 30s 调大为 60s,发现没有成果,于是又调大到 90s,惋惜还是不见效,服务还是呈现始终重启的设想。
2)接下来是狐疑 pod 所在的宿主机会不会是内存不足导致的呢?于是登陆宿主机查看内存
$ free -m
总内存 128g, 可用内存有 60g 以上,宿主机的物理内存是足够的。
3)主机内存也是失常的,不晓得 JVM 的监控是否有显著的异样提醒呢?
到这个时候,间隔降级曾经过来 2 小时了。于是关上业务 jvm 的 heap 和 gc 次数监控看板,发现 full gc 还是比拟法则的,没有明细的异样信息。
此时间隔降级曾经过来将近 3 小时了。切实找不到任何脉络了,难道只能回滚了吗?
4)最初的最初,咱们想到查看零碎级别日志看看是否有异样提醒,后果终于发现 OOM 的谬误日志。
dmesg -T
论断:
到这里问题曾经比拟显著了,pod 外部的 Java 服务异样申请内存超过内存下限(该 pod 配置的的内存 limit 值是 4g)触发了零碎的 killer 爱护过程将 pod 过程 kill 掉。
4、根因定位
尽管定位到是 OOM 起因导致的,然而为什么降级了 JDK 就导致 OOM 呢?
通过 jinfo 命令查看 JVM 启动参数终于发现根本原因。原来服务重复 OOM 被 kill 掉是因为“-XX:MaxHeapSize”参数生效导致 Java 过程应用默认值 32g(物理机的 1 /4)超出了 pod 调配的 limit 下限 8g。那为什么“-XX:MaxHeapSize”参数生效呢?那是因为新镜像给 JAVA_OPS 进行默认赋值,笼罩了之前启动参数 JAVA_OPS 的值。想要解决这个问题,须要勾销 OpenJDK 镜像对于 JAVA_OPS 的默认赋值。
jinfo -flags 1
再次确认 MaxHeapSize 的默认值,通过执行以下命令能够看到 MaxHeapSize 默认值的确是零碎总内存的
1/4。
java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
5、总结复盘
联合本次公布引起的异样做一次复盘,次要蕴含问题产生和修复实现的工夫点以及故障起因剖析与优化措施。见如下表格: