You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus原生服务部署在K8S集群时,如何借助线程/堆Dump排查性能问题?

在K8S中部署Quarkus原生服务的性能排查方案

一、解决Pod内缺失jmap、jstack、ps命令的问题

Quarkus原生镜像为了轻量化,默认不会包含JDK工具(jmap/jstack)和ps这类系统命令,给你两种实用解决思路:

  • 构建镜像时预装工具
    修改Quarkus的镜像构建配置,在生成的原生镜像中添加所需工具。比如基于ubi-minimal镜像的话,可以通过microdnf安装procps(包含ps),再从GraalVM镜像复制jmap/jstack:

    FROM quay.io/quarkus/quarkus-micro-image:2.0
    COPY --from=builder /workspace/application /workspace/application
    # 安装ps命令
    RUN microdnf install -y procps && microdnf clean all
    # 从GraalVM镜像复制JDK工具
    COPY --from=graalvm/graalvm-ce:latest /usr/lib/jvm/graalvm-ce/bin/jmap /usr/bin/jmap
    COPY --from=graalvm/graalvm-ce:latest /usr/lib/jvm/graalvm-ce/bin/jstack /usr/bin/jstack
    

    注意:原生应用是本地二进制程序,JDK工具不一定能直接兼容,优先用后面提到的Quarkus原生排查手段。

  • 临时挂载工具容器
    用kubectl debug给目标Pod挂载一个带工具的容器,共享进程空间直接使用:

    kubectl debug -it <你的Pod名称> --image=busybox --share-processes
    

    进入这个busybox容器后,就能用ps命令,也可以在这里直接分析目标进程。

二、获取Quarkus原生服务的Thread Dump

Quarkus原生应用基于GraalVM,获取Thread Dump有两种简单可行的方式:

1. 信号触发(最便捷)

给Pod内的应用进程(一般PID是1)发送SIGQUIT信号,Thread Dump会直接输出到Pod日志:

kubectl exec <Pod名称> -- kill -QUIT 1
# 查看日志获取dump内容
kubectl logs <Pod名称>

2. 通过Quarkus管理端点获取

在application.properties中开启管理端点:

quarkus.management.enabled=true
quarkus.management.endpoints.web.exposure.include=thread-dump

部署后用端口转发访问端点:

kubectl port-forward <Pod名称> 9001:9001
curl http://localhost:9001/q/management/thread-dump

三、获取Quarkus原生服务的Heap Dump

原生应用的堆是GraalVM的原生堆,需要用对应工具处理:

1. 信号生成Heap Dump

给进程发送SIGUSR1信号,会在应用目录生成heapdump.hprof文件:

kubectl exec <Pod名称> -- kill -USR1 1
# 复制到本地分析
kubectl cp <Pod名称>:/workspace/heapdump.hprof ./heapdump.hprof

2. 用GraalVM的jmap生成

如果已经预装了GraalVM的jmap,直接执行:

kubectl exec <Pod名称> -- jmap -dump:format=b,file=heapdump.hprof 1

同样用kubectl cp把文件拷回本地。

3. 分析Heap Dump

用GraalVM自带的VisualVM或者native-image-inspector工具分析:

# 用native-image-inspector分析堆dump
native-image-inspector --heap-dump heapdump.hprof

四、定位性能问题代码块的步骤

  1. 多次捕获Thread Dump:间隔10-30秒取3-5份,找长期处于RUNNABLE(CPU占用高)或BLOCKED(锁等待)状态的线程,重复出现的栈帧就是问题代码的位置。
  2. 分析Heap Dump:查看哪些对象实例数量多、占内存大,追溯对象的创建链路,定位内存泄漏或过度分配的代码段。
  3. 结合应用日志:把Thread Dump里的线程栈和日志中的错误、慢请求日志关联,锁定具体业务逻辑。
  4. 新旧版本对比:如果是新版本才出现的问题,对比旧版本的Dump数据,找出差异点。

内容的提问来源于stack exchange,提问作者Tam Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:10:19