How to use Arthas in Docker container

Posted by oakld on Thu, 02 Dec 2021 05:29:25 +0100

What can Arthas do for you?

Arthas is an open source Java diagnostic tool of Alibaba, which is deeply loved by developers.

When you encounter the following similar problems and are helpless, Arthas can help you solve them:

  1. Which jar package is this class loaded from? Why are all kinds of related exceptions reported?
  2. Why didn't the code I changed execute? Am I not commit ted? Wrong branch?
  3. You can't debug online when you encounter a problem. Can you only republish it by adding a log?
  4. There is a problem with the data processing of a user online, but it is also impossible to debug online and reproduce offline!
  5. Is there a global perspective to view the health of the system?
  6. Is there any way to monitor the real-time running status of the JVM?
  7. How to quickly locate application hotspots and generate flame diagrams?
  8. How do I find an instance of a class directly from within the JVM?

Arthas supports JDK 6 +, Linux/Mac/Windows, adopts command-line interaction mode, and provides rich Tab automatic completion functions to further facilitate problem location and diagnosis.

Please refer to the official documents for details. Each command has a detailed description: https://arthas.aliyun.com/doc/

This article is not about how to use arthas. Here is how to use arthas in our docker container.

Since it is very complicated for us to use arthas in the docker container, we need to find the container id, copy the entire arthas directory into the container, enter the container, and start arthas for users who need to switch to the target service. These steps are not friendly to many students who are not familiar with linux commands and docker commands.

Therefore, I wrote a script that can directly replace the above steps, as shown in the following figure:

Directly after the script, enter the complete service name (here is the IMAGE name of the container), which is simple and convenient.

usage method:

  1. First, you need to unzip arhas-bin.zip on the linux server, and the extracted arhas software is arthas. Make sure docker is installed on this computer

Download Directory: https://github.com/alibaba/arthas/releases

  1. Put the arthasDocker.sh script into the arthas directory just extracted, open the script, and edit arthas_ The path variable is changed to the directory where you put arthas.

Contents of arthasDocker.sh script:

#!/bin/bash
#
# author: Liu Liyuan
# date: 2020-8-20 18:14:38
# desc: this script needs to be put into the directory of arthas and copied to the docker container together with the whole directory. The main purpose is to switch users of the target service in the container and start arthas

echo "Start the process of querying the target service id And users..."
PID=`ps -eo pid,user=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -o args | grep java | grep -v grep | awk '{print $1}'`
echo "Process of target service id by ${PID}"
USER=`ps -eo pid,user=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -o args | grep java | grep -v grep | awk '{print $2}'`
echo "The user of the target service is ${USER}"

if [[ ! -d "/home/${USER}" ]]
then
  mkdir -p /home/${USER}
  echo "Create directory/home/${USER}"
fi
chmod 777 /home/${USER}

echo "Start switching users and start arthas..."
# The following arthas path needs to be modified and consistent with the startArthas.sh script
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}"
  1. Put the startArthas.sh script on the linux server. It is recommended to put it in the ~ directory. Open the script and edit arthas_ The path variable is changed to the directory where you put arthas. Then give the script execution permission

Contents of startArthas.sh script:

#! /bin/bash
#
# author: Liu Liyuan
# date: 2020-9-18 10:36:27
# desc: this script is mainly used to start the arthas diagnostic tool to diagnose java services in a docker

if [[ ${1} == '' ]]
then
  echo "Please select a service:"
  sudo docker ps | awk 'NR>1 {print $2}'
  exit 0
fi

echo "Start looking for services ${1}Container for..."
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 "The container for this service was not found. Please reselect the service:"
    sudo docker ps | awk 'NR>1 {print $2}'
  else
    echo "Please enter the full name of the service:"
    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 "Find container ${ID}"

  echo "Start copying arthas Into container..."
  # The following arthas path needs to be modified and consistent with that in the arthasDocker.sh script
  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 "copy complete"

  echo "About to enter the container..."
  sudo docker exec -it ${ID} /bin/bash -c "bash ${ARTHAS_PATH}/arthasDocker.sh"
fi
  1. Finally, just run the startArthas.sh script directly

Topics: Linux Docker