专业的编程技术博客社区

网站首页 > 博客文章 正文

Java通过K8S部署的服务的一次崩溃排查记录

baijin 2024-11-12 09:37:54 博客文章 2 ℃ 0 评论

首先,服务崩溃我们是根据pod的RESTARTS的值,那么pod重启一次,即崩溃一次。

服务是有5个实例,每天都有崩溃,频繁崩溃时能达到一天5-8次。

崩溃有两个方向导致,分别是:

1.k8s删除pod,因为pod内存或cpu超限,导致被删除后重启。

2.Java服务退出,因为是主进程,pod重启。

分别分析:

1.如果是pod侧被删除,那么k8s是有事件记录的,如下形式,经排查,pod事件也是正常的。

同时我们的容器只设置了request,没有设置limit,那么不可能是pod超限被删除。再有就是机器的内存不足导致的,查看esc机器内存平稳无问题。

2.Java服务退出,设置-XX:ErrorFile=***,查看是否有Java退出的情况。我们线上的情况是

看到summary中

Problematic frame:
# V  [libjvm.so+0x6992ca]  G1ParCopyClosure<(G1Barrier)0, (G1Mark)0>::do_oop(unsigned int*)+0x5a

V 表明是 VMframe 函数帧。

Current thread (0x00005651ec9a2d60):  GCTaskThread "GC Thread#0" [stack: 0x00007fabdb12e000,0x00007fabdb22eaa8] [id=12]

表明发生错误的线程。

再往下看到

JavaThread 0x00005651f9c25ea0 (nid = 125) was being processed
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v  ~RuntimeStub::_new_array_Java
J 16116 c2 cn.hutool.core.util.ReflectUtil.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object; (189 bytes) @ 0x00007fabe90cf244 [0x00007fabe90ce640+0x0000000000000c04]
J 16700 c2 cn.hutool.core.bean.copier.BeanCopier$Lambda$2347+0x0000000801ae2e58.accept(Ljava/lang/Object;)V (28 bytes) @ 0x00007fabe912df80 [0x00007fabe912d7a0+0x00000000000007e0]

此处开始有我们业务的线程信息。先查看了hutool的讨论,发现确实有问题,gitee的issues区:I5AGFK。

我们是使用了hutool中的BeanUtil.copyProperties,同时我们使用的jdk15。这时初步判定是它引发的崩溃。它并不是所有的对象复制有问题,是当访问量大时,才会引发问题。

我们采用对象复制改为JSON的形式,移除掉hutool的BeanUtil.copyProperties,来观察线上服务的运行情况。验证到同样甚至更多访问量时,服务未出现崩溃的情况。

引发的思考:

Java的业务服务中经常用到数据库层查询出来的对象,转换成展示层的对象,那么对象复制该用什么方法呢?

1.反射

Spring中的BeanUtils.copyProperties。存在问题:在spring 5.3.0 版本后,两个类中都含有泛型的属性,当泛型类型不一致时,不进行复制。

hutool中的BeanUtil.copyProperties。在JDK15中(中间版本未测试),调用量升高后,引入JDK报错退出。

2.JSON序列化。

3.手动set。可考虑使用MapStruct框架。当业务代码已经积累很多时,此种改动成本较高。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表