一, 发现问题
在一次系统上线后, 我们发现某几个节点在长时间运行后会出现 CPU 持续飙升的问题, 导致的结果就是 Kubernetes 集群的这个节点会把所在的 Pod 进行驱逐 (调度); 如果调度到同样问题的节点上, 也会出现 Pod 一直起不来的问题. 我们尝试了杀死 Pod 后手动调度的办法 (label), 当然也可以排除调度节点. 但是在一段时间后还会复现, 我们通过监控系统也排查了这段时间的流量情况, 但应该和 CPU 持续占用没有关联, 这时我们意识到这可能是程序的问题.
二, 排查问题
定位 Pod
这里使用 kubectl top pods 命令确定 CPU 占用最高的 pods 都是哪些.
kubectl -n App top pods
因为问题已解决, 以上图片只是举个例子.
排查工具
Arthas
我们这边使用了阿里的 Arthas , 它是 Alibaba 开源的 Java 诊断工具. 当你遇到以下类似问题而束手无策时, Arthas 可以帮助你解决:
这个类从哪个 jar 包加载的? 为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到? 难道是我没 commit? 分支搞错了?
遇到问题无法在线上 debug, 难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题, 但线上同样无法 debug, 线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到 JVM 的实时运行状态?
怎么快速定位应用的热点, 生成火焰图?
排查问题
定位到有问题的 Pod 后, 使用 kubectl exec 进入 Pod 容器内部:
kubectl -n App exec -it 49a89b2f-73c6-40ac-b6de-c6d0e47ace64-5d489d9c48qwc7t -- /bin/bash
在容器中下载 Arthas
wget https://arthas.gitee.io/arthas-boot.jar
由于我们打包镜像中只有一个服务, 所以一个 Pod 中也只有一个进程; 这里 1 是指 PID.
java -jar arthas-boot.jar 1
执行进程看板 dashboard:
[arthas@1]$ dashboard
这里上半区显示了线程内容, 我们可以看到哪个线程 ID 的对应情况:
比如从上面得到了线程 ID, 使用如下命令进入线程, 如 ID 12262:
[arthas@1]$ thread -n 12262
打印出线程日志:
- [arthas@1]$ thread -n 12262
- "com.alibaba.nacos.client.Worker.addr-bj-internal.edas.aliyun.com-7362814c-538b-4c26-aa07-1fd47765a145" Id=20190 cpuUsage=7% TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@d30d0a4e (in native)
- at sun.misc.Unsafe.park(Native Method)
- - waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@d30d0a4e
- at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
- at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
- at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
- at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
- at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
- at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- at java.lang.Thread.run(Thread.java:813)
三, 解决问题
经过了排查定位到了问题, 最后经过社区和阿里云伙伴的协助, 发现了这个是 Nacos 2.0.0.RELEASE 的一个 BUG. 我们对 Nacos 客户端版本进行了升级, 经过测试后, 问题解决了. 也加深了对 Kubernetes 集群调试的能力 [加油].
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- <version>2.0.1.RELEASE</version>
- </dependency>
四, 最后
通过社区和阿里云的帮助, 问题成功解决. 在工具方面, 阿里提供的 Arthas, 真的是线上环境调试神器!
来源: https://www.cnblogs.com/maxzhang1985/p/12673160.html