docker中如何使用Arthas诊断工具

13 阅读4分钟

要在Docker中使用Arthas(Java线上诊断工具),需遵循预装集成(推荐生产环境)或临时安装(适合临时排查)的流程,并确保容器环境满足JDK要求(Arthas依赖JDK工具链,如jcmdtools.jar)。以下是详细步骤和最佳实践:

一、前置条件

  1. 容器基础镜像:需使用JDK镜像(而非JRE),如openjdk:8-jdk-alpineopenjdk:11-jdk,避免因缺少JDK工具导致Arthas无法启动。
  2. Arthas安装包:推荐使用离线全量包arthas-bin.zip),适合生产环境(无外网访问);临时排查可使用在线下载。

二、方法1:预装Arthas到Docker镜像(推荐)

通过在Dockerfile中集成Arthas,使每个容器启动时自动具备诊断能力,适用于生产环境。

步骤1:准备Arthas离线包

从GitHub Releases下载最新Arthas全量包(如arthas-all-4.0.5.zip),解压后得到arthas目录(包含arthas-boot.jararthas-core.jar等文件)。

步骤2:编写Dockerfile

在Java项目根目录创建Dockerfile,复制Arthas离线包和应用JAR包,并设置启动脚本(先启动应用,再延迟Attach Arthas)。示例:

# 使用JDK基础镜像(必须)
FROM openjdk:8-jdk-alpine

# 创建Arthas目录
RUN mkdir -p /opt/arthas

# 复制Arthas离线包到容器
COPY ./arthas /opt/arthas/

# 复制应用JAR包(替换为你的应用路径)
COPY target/your-app.jar /app.jar

# 启动脚本:先启动应用,延迟15秒后Attach Arthas(确保应用完全启动)
CMD java -jar /app.jar & \
    sleep 15 && \
    java -jar /opt/arthas/arthas-boot.jar \
    --tunnel-server 'ws://tunnel-server:7777/ws' \  # 可选:连接Arthas Tunnel Server(集中管理)
    --app-name myapp \                              # 应用名称(用于Tunnel识别)
    --telnet-port 3658 \                            # Telnet端口(默认3658)
    --http-port 8563                                # HTTP端口(默认8563)

说明sleep 15是关键,确保应用完全启动后再Attach Arthas,避免因应用未就绪导致Attach失败。

步骤3:构建镜像并运行容器

# 构建镜像(替换为你的镜像名称)
docker build -t your-app:with-arthas .

# 运行容器(映射端口,确保Tunnel Server可访问)
docker run -d --name your-app-container \
    -p 8080:8080 \  # 应用端口
    -p 3658:3658 \  # Arthas Telnet端口(可选)
    -p 8563:8563 \  # Arthas HTTP端口(可选)
    your-app:with-arthas

步骤4:使用Arthas诊断

进入容器或通过Tunnel Server连接Arthas:

# 进入容器
docker exec -it your-app-container /bin/sh

# 启动Arthas(若未自动启动)
java -jar /opt/arthas/arthas-boot.jar

此时会列出容器中的Java进程(如your-app.jar),输入编号即可Attach,进入Arthas交互界面。

三、方法2:临时在容器中安装Arthas(适合临时排查)

若仅需临时诊断某个容器,可通过以下步骤在线或离线安装Arthas:

步骤1:进入运行中的容器

docker exec -it your-app-container /bin/sh

步骤2:安装JDK工具(若基础镜像为JRE)

若容器使用JRE镜像(如openjdk:8-jre-alpine),需安装JDK工具(如openjdk-8-jdk),否则Arthas无法正常工作:

# Alpine镜像安装JDK
apk add --no-cache openjdk8-jdk

# Debian/Ubuntu镜像安装JDK
apt-get update && apt-get install -y openjdk-8-jdk

步骤3:下载并启动Arthas

  • 在线下载(需容器联网):

    wget https://arthas.aliyun.com/arthas-boot.jar
    java -jar arthas-boot.jar
    
  • 离线下载(推荐生产环境):

    在本地下载arthas-boot.jar,通过docker cp复制到容器:

    # 本地下载
    wget https://arthas.aliyun.com/arthas-boot.jar
    
    # 复制到容器
    docker cp arthas-boot.jar your-app-container:/tmp/
    
    # 进入容器并启动
    docker exec -it your-app-container /bin/sh
    java -jar /tmp/arthas-boot.jar
    

步骤4:Attach到Java进程

启动arthas-boot.jar后,会列出容器中的Java进程(如your-app.jar),输入编号即可Attach,进入Arthas交互界面。

四、Arthas常用命令(实战场景)

Attach成功后,可使用以下命令诊断应用:

命令场景说明示例
dashboard实时查看JVM状态(线程、内存、GC)dashboard(输入Q退出)
thread -n 5查看CPU占用最高的5个线程thread -n 5
thread --deadlock检查死锁线程thread --deadlock
sc -d com.example.OrderController查看类的加载信息(来源JAR、类加载器)sc -d com.example.OrderController
watch com.example.OrderController createOrder '{params, returnObj}' -x 3观察方法入参和返回值(某用户下单失败时用)watch com.example.OrderController createOrder '{params, returnObj}' -x 3
trace com.example.OrderService payOrder追踪方法调用链(定位接口慢的原因)trace com.example.OrderService payOrder
jad com.example.OrderService反编译类(验证线上代码是否为最新版本)jad com.example.OrderService > /tmp/OrderService.java

五、最佳实践

  1. 使用Arthas Tunnel Server:集中管理多容器/多Pod的诊断会话,无需SSH登录容器,支持权限控制和审计。

    • 部署Tunnel Server:helm install arthas arthas/arthas-k8s(K8s环境)或从GitHub下载FatJar运行。
    • 启动Arthas时连接Tunnel:java -jar arthas-boot.jar --tunnel-server 'ws://tunnel-server:7777/ws'
  2. 离线部署:生产环境禁用远程下载,使用离线包(arthas-bin.zip)预装到镜像。

  3. 安全控制:限制Arthas端口(如3658、8563)的访问范围,避免暴露到公网。

总结

在Docker中使用Arthas的核心是确保容器有JDK环境,并通过预装集成(推荐)或临时安装(临时排查)启动Arthas。通过dashboardthreadwatch等命令,可快速定位线上问题(如CPU高、接口慢、死锁)。结合Arthas Tunnel Server,可实现多容器的集中管理,提升诊断效率。