如何在Docker容器中使用Arthas
Arthas(阿尔萨斯) 能为你做什么?
Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时,
Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从JVM内查找某个类的实例?
Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的Tab自动补全功能,进一步方便进行问题的定位和诊断。
具体内容请查看官方文档,各个命令有详细的说明: https://arthas.aliyun.com/doc/
本文不是介绍arthas怎么用的。这里要说的是,如何在我们的docker容器中,使用arthas。
鉴于我们在docker容器中使用arthas十分复杂,需要找到容器id,需要复制整个arthas目录到容器中,需要进入容器,需要切换到目标服务的用户,需要启动arthas,这些步骤对于很多对linux命令和docker命令不熟悉的同学并不友好。
因此我写了个脚本,可以直接替代以上步骤,使用方法如下图所示:

直接在脚本后,输入完整的服务名(这里取的是容器的IMAGE名称),即可使用,简单便捷。
使用方法:
- 首先需要在linux服务器上解压arhas-bin.zip,解压出来即是arthas软件。确保本机已安装docker
下载目录:https://github.com/alibaba/arthas/releases
- 将arthasDocker.sh脚本,放到刚才解压的arthas目录中,打开脚本,编辑ARTHAS_PATH变量,改为你arthas放置的目录。
arthasDocker.sh脚本内容:
#!/bin/bash
#
# author: 刘力源
# date: 2020-8-20 18:14:38
# desc: 本脚本需要放到arthas的目录中,连同整个目录一起复制到docker容器中去。主要用途为在容器中切换目标服务的用户,并启动arthas
echo "开始查询目标服务的进程id和用户..."
PID=`ps -eo pid,user=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -o args | grep java | grep -v grep | awk '{print $1}'`
echo "目标服务的进程id为${PID}"
USER=`ps -eo pid,user=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -o args | grep java | grep -v grep | awk '{print $2}'`
echo "目标服务的用户为${USER}"
if [[ ! -d "/home/${USER}" ]]
then
  mkdir -p /home/${USER}
  echo "创建目录/home/${USER}"
fi
chmod 777 /home/${USER}
echo "开始切换用户并启动arthas..."
# 下面的arthas路径需要修改,并且要和startArthas.sh脚本中保持一致
ARTHAS_PATH="/opt/arthas"
su ${USER} -c "java -jar ${ARTHAS_PATH}/arthas-client.jar 127.0.0.1 3658 -c 'stop'"
su ${USER} -c "java -jar ${ARTHAS_PATH}/arthas-boot.jar ${PID}"
- 将startArthas.sh脚本,放到linux服务器上,建议放到~目录下,打开脚本,编辑ARTHAS_PATH变量,改为你arthas放置的目录。然后赋予脚本执行权限
startArthas.sh脚本内容:
#! /bin/bash
#
# author: 刘力源
# date: 2020-9-18 10:36:27
# desc: 本脚本主要用途为启动arthas诊断工具来诊断某个docker中java服务
if [[ ${1} == '' ]]
then
  echo "请选择一个服务:"
  sudo docker ps | awk 'NR>1 {print $2}'
  exit 0
fi
echo "开始寻找服务${1}的容器..."
DOCKER_LIST=`sudo docker ps | awk 'NR>1 {print $2}'`
FLAG=0
for i in ${DOCKER_LIST[@]}
do
  if [[ ${i} == ${1} ]]
  then
    FLAG=1
    break
  fi
done
if [[ ${FLAG} == 0 ]]
then
  DOCKER_NAME=`sudo docker ps | awk 'NR>1 {print $2}' | grep ${1}`
  if [[ ${DOCKER_NAME} == '' ]]
  then
    echo "未找到该服务的容器,请重新选择服务:"
    sudo docker ps | awk 'NR>1 {print $2}'
  else
    echo "请输入服务的完整名称:"
    sudo docker ps | awk 'NR>1 {print $2}' | grep ${1}
  fi
else
  ID=`sudo docker ps --filter ancestor=${1} | awk '{print $1}' | sed -n '2p'`
  echo "找到容器${ID}"
  echo "开始复制arthas到容器中..."
  # 下面的arthas路径需要修改,并且要和arthasDocker.sh脚本中保持一致
  ARTHAS_PATH="/opt/arthas"
  sudo docker exec -it ${ID} /bin/bash -c "rm -rf ${ARTHAS_PATH}"
  sudo docker cp ${ARTHAS_PATH} ${ID}:${ARTHAS_PATH}
  echo "复制完成"
  echo "即将进入容器中..."
  sudo docker exec -it ${ID} /bin/bash -c "bash ${ARTHAS_PATH}/arthasDocker.sh"
fi
- 最后直接运行 startArthas.sh 脚本就可以了
如何在Docker容器中使用Arthas的更多相关文章
- 如何在 Docker 容器中运行 Kali Linux 2.0
		https://linux.cn/article-6103-1.html Kali Linux 是一个对于安全测试人员和白帽的一个知名操作系统.它带有大量安全相关的程序,这让它很容易用于渗透测试.最近 ... 
- Linux下将.Asp Core 部署到 Docker容器中
		我们来部署一个简单的例子: 将一个简单的.Aps Core项目部署到Docker容器中并被外网访问 说明: 下面的步骤都是建立在宿主服务器系统已经安装配置过Docker容器,安装Docker相对比较简 ... 
- 如何在Docker容器之间拷贝数据
		[编者的话]在容器之间拷贝数据是Docker一个重要而且基本的功能.拷贝数据到其他容器是一个经常使用到的场景,如当服务器遇到不可预见的“灾难”(注:断电,宕机)时,起到备份数据的作用.本文作者详细介绍 ... 
- Docker容器中运行ASP.NET Core
		在Linux和Windows的Docker容器中运行ASP.NET Core 译者序:其实过去这周我都在研究这方面的内容,结果周末有事没有来得及总结为文章,Scott Hanselman就捷足先登了. ... 
- 在 docker 容器中捕获信号
		我们可能都使用过 docker stop 命令来停止正在运行的容器,有时可能会使用 docker kill 命令强行关闭容器或者把某个信号传递给容器中的进程.这些操作的本质都是通过从主机向容器发送信号 ... 
- Docker容器中开始.NETCore之路
		一.引言 开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境 ... 
- 隔离 docker 容器中的用户
		笔者在前文<理解 docker 容器中的 uid 和 gid>介绍了 docker 容器中的用户与宿主机上用户的关系,得出的结论是:docker 默认没有隔离宿主机用户和容器中的用户.如果 ... 
- Docker容器中开始.Net Core之路
		开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境,服务器也 ... 
- Docker容器中找不到vim命令
		docker容器中,有的并未安装vi和vim,输入命令vim,会提示vim: command not found(如下图).此时我们就要安装vi命令 执行命令:apt-get update apt-g ... 
随机推荐
- 更好的 java 重试框架 sisyphus 背后的故事
			sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活. 今天,让我们一起看一下西西弗斯背后的故事. 情景导入 简单的需求 产品经理:实现一个 ... 
- Django Model字段加密的优雅实现
			早前的一篇文章Django开发密码管理表实例有写我们写了个密码管理工具来实现对密码的管理,当时加密解密的功能在view层实现,一直运行稳定所以也没有过多关注实现是否优雅的问题.最近要多加几个密码表再次 ... 
- 【UE4】读写 Texture 数据
			创建texture 方式一 void AActor_Assignment2::TextureFromImage_Internal( const TArray<FColor>& Sr ... 
- spring session实现session统一管理(jdbc实现)
			最近在看一些关于spring session 的知识,特做一个笔记记录一下. 在项目中经常会遇到这么一种情况,同一个web项目有时需要部署多份,然后使用nginx实现负载均衡,那么遇到的问题就是,部署 ... 
- 高斯消元de小板几
			感觉就是模拟解方程,还比手动解方程笨一些.... 但是大数据的话,他毕竟比我解得快多了.... 1 inline int Gauss(int n){ 2 int cnt=1;//真实到达的行列式行数 ... 
- Redis的浅入门
			Redis的浅入门 # 缓存的思想 问题提出:我们的用户数量上亿,如果登录,访问数据库user特别耗时,该怎么办?--提出缓存 方法:怎样从缓存在获取数据? *有数据: 直接返回 *无数据: (1)从 ... 
- [个人开源]vue-code-view:一个在线编辑、实时预览的代码交互组件
			组件简介 vue-code-view是一个基于 vue 2.x.轻量级的代码交互组件,在网页中实时编辑运行代码.预览效果的代码交互组件. 使用此组件, 不论 vue 页面还是 Markdown 文档中 ... 
- 通用 Makefile(及makefile中的notdir,wildcard和patsubst)
			notdir,wildcard和patsubst是makefile中几个有用的函数,以前没留意过makefile中函数的用法,今天稍微看看~ 1.makefile里的函数 makefile里的函数使用 ... 
- hdu 4786 Fibonacci Tree (最小、最大生成树)
			题意: N个点,M条边.每条边连接两个点u,v,且有一个权值c,c非零即一. 问能否将N个点形成一个生成树,并且这棵树的边权值和是一个fibonacii数. (fibonacii数=1,2,3,5,8 ... 
- 【数据结构&算法】04-线性表
			目录 前言 线性表的定义 线性表的数据类型&操作 线性表操作 数据类型定义 复杂操作 线性表的顺序存储结构 顺序存储结构的定义 顺序存储方式 数据长度和线性表长度的区别 地址的计算方法 顺序存 ... 
