docker中如何使用Arthas诊断工具

要在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)。示例:

bash 复制代码
# 使用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:构建镜像并运行容器

yaml 复制代码
# 构建镜像(替换为你的镜像名称)
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:

bash 复制代码
# 进入容器
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:进入运行中的容器

bash 复制代码
docker exec -it your-app-container /bin/sh

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

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

csharp 复制代码
# Alpine镜像安装JDK
apk add --no-cache openjdk8-jdk

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

步骤3:下载并启动Arthas

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

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

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

    bash 复制代码
    # 本地下载
    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,可实现多容器的集中管理,提升诊断效率。

相关推荐
rustfs3 小时前
使用 RustFS和 Arq,打造 PC 数据安全备份之道
分布式·docker·云原生·rust·开源
橙子❦4 小时前
官网下载docker--centos容器,后安装并启动容器
docker·容器·centos
自己的九又四分之三站台4 小时前
Docker + Ollama 大模型管理
docker·容器·eureka
小钱c74 小时前
记录一次WSL修改networkingMode导致Docker端口无法访问的问题
运维·docker·容器
懒人村杂货铺5 小时前
从 Permission Denied 到 404:Docker 多容器下图片上传与静态资源服务全解
docker·fastapi
战南诚5 小时前
docker拉取nginx镜像失败(m4/arm64架构)
docker
阿杰 AJie5 小时前
Docker 常用指令和使用方法
docker·容器·eureka
风一样的男子&6 小时前
kylin桌面版v10安装docker和k8s
docker·kubernetes·kylin
阿杰 AJie6 小时前
Docker 启动参数速查表(全镜像通用)
运维·docker·容器