文章目录
- arthas-boot
- Bootstrap
 

arthas-boot
该module 的代码只有3个类:
 
Bootstrap
启动类 Bootstrap ,开头的注解就是 alibaba 的 cli 中间件,和 picocli 蛮像。
 
 arthas 在一些命令的执行需要有 JDK 命令的支持,以 ProcessUtils.select 为例,该方法实际上是要调用JAVA_HOME 下的 jps
jps -l
		long pid = bootstrap.getPid();
        // select pid
        if (pid < 0) {
            try {
                pid = ProcessUtils.select(bootstrap.isVerbose(), telnetPortPid, bootstrap.getSelect());
            } catch (InputMismatchException e) {
                System.out.println("Please input an integer to select pid.");
                System.exit(1);
            }
            if (pid < 0) {
                System.out.println("Please select an available pid.");
                System.exit(1);
            }
        }
选择 pid 后下载相关依赖:
 
 
 后面就是启动关键模块 arthas-core
 
 也就是说又启动了一个java进程:
 
 这就理解了 arthas 提升要用 stop 命令来推出,而不是关闭当前命名窗口,它是个多进程应用。
 
之后构建 ProcessBuilder 执行命令:
        // "${JAVA_HOME}"/bin/java \
        // ${opts} \
        // -jar "${arthas_lib_dir}/arthas-core.jar" \
        // -pid ${TARGET_PID} \
        // -target-ip ${TARGET_IP} \
        // -telnet-port ${TELNET_PORT} \
        // -http-port ${HTTP_PORT} \
        // -core "${arthas_lib_dir}/arthas-core.jar" \
        // -agent "${arthas_lib_dir}/arthas-agent.jar"
并将进程的标准输出、标准错误进行重定向:
ProcessBuilder pb = new ProcessBuilder(command);
        // https://github.com/alibaba/arthas/issues/2166
        pb.environment().put("JAVA_TOOL_OPTIONS", "");
        try {
            final Process proc = pb.start();
            Thread redirectStdout = new Thread(new Runnable() {
                @Override
                public void run() {
                    InputStream inputStream = proc.getInputStream();
                    try {
                        IOUtils.copy(inputStream, System.out);
                    } catch (IOException e) {
                        IOUtils.close(inputStream);
                    }
                }
            });
            Thread redirectStderr = new Thread(new Runnable() {
                @Override
                public void run() {
                    InputStream inputStream = proc.getErrorStream();
                    try {
                        IOUtils.copy(inputStream, System.err);
                    } catch (IOException e) {
                        IOUtils.close(inputStream);
                    }
                }
            });
            redirectStdout.start();
            redirectStderr.start();
            redirectStdout.join();
            redirectStderr.join();
            int exitValue = proc.exitValue();
            if (exitValue != 0) {
                AnsiLog.error("attach fail, targetPid: " + targetPid);
                System.exit(1);
            }
最终看到这个:
 



















