• arthas在线改代码初体验【arthas学习一】


    一、背景

    很久之前就有一个想法:如果部署在线上的代码在遇到类似空指针异常时能自动修复就好了。前段时间准备尝试落实这个想法。那就先从基础做起:先在线改代码吧!

    本来我是在学习字节码的,偶尔搜了一下资料,发现Arthas这个工具,能够实现代码热修改。

    我仿佛发现了新大陆,于是添加收藏。这时我发现,我的收藏夹里很早就收藏了这个网页。看来有些路终究是要走的。

    废话不说,试试吧!

    二、准备

    1、下载Arthas到电脑

    直接从官网下就行。下那个最全的包,解压就好。

    https://arthas.aliyun.com/doc/quick-start.html

    2、写个小项目

    我写了个springboot项目,里面主要就两个方法。

    1)HelloController

    @RestController
    public class HelloController {
        @GetMapping("/hello1")
        public String hello1(@RequestParam(value="name", defaultValue="world") String name) {
            return StringUtil.packHello(name);
        }
    }

    2)StringUtil

    public class StringUtil {
        public static String packHello(String name) {
            return String.format("Hello %s!", name);
        }
    }

    三、开始

    1、启动springboot项目

    2、运行arthas,并选择目标进程

    我这里选择2

    java -jar arthas-boot.jar
    [INFO] arthas-boot version: 3.6.0
    [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
    * [1]: 6784 org.jetbrains.jps.cmdline.Launcher
    [2]: 6787 com.shuimutong.learn.arthos.helloweb.HelloWebApplication

    3、使用sc命令查找要修改的类

    我这里准备在StringUtil里加上一个打印,输入查找命令如下:

    [arthas@6787]$ sc -d *util.StringUtil
    class-info com.shuimutong.learn.arthos.helloweb.util.StringUtil
    code-source /Users/zhengxingao/Documents/develop/arthoslearn/helloweb/target/classes/
    name com.shuimutong.learn.arthos.helloweb.util.StringUtil
    isInterface false
    isAnnotation false
    isEnum false
    isAnonymousClass false
    isArray false
    isLocalClass false
    isMemberClass false
    isPrimitive false
    isSynthetic false
    simple-name StringUtil
    modifier public
    annotation
    interfaces
    super-class +-java.lang.Object
    class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
    +-sun.misc.Launcher$ExtClassLoader@32a1bec0
    classLoaderHash 18b4aac2

    4、使用jad命令反编译出源码

    jad --source com.shuimutong.learn.arthos.helloweb.util.StringUtil > /tmp/StringUtil.java

    输出目录建议选择/tmp,不用担心没有权限

    5、编辑/tmp/StringUtil.java

    arthas里面没法使用vi,所以新开窗口编辑吧。

           /*
            * Decompiled with CFR.
            */
           package com.shuimutong.learn.arthos.helloweb.util;
    
           public class StringUtil {
               public static String packHello(String name) {
                   System.out.println("name:"+name);
    /* 5*/         return String.format("Hello %s!", name);
               }
           }

    我加了个打印。

    (那个/*5*/我也不知道咋回事,后面再了解吧)

    6、编译文件

    mc -c 18b4aac2 /tmp/StringUtil.java -d /tmp
    Memory compiler output:
    /tmp/com/shuimutong/learn/arthos/helloweb/util/StringUtil.class
    Affect(row-cnt:1) cost in 194 ms.

    -c后面跟的一串是字符是前面查找类时打印出的classLoadHash

    7、加载编译的class

    [arthas@6787]$ redefine /tmp/com/shuimutong/learn/arthos/helloweb/util/StringUtil.class
    redefine success, size: 1, classes:
    com.shuimutong.learn.arthos.helloweb.util.StringUtil

    8、检验

    请求:http://localhost:8081/hello1?name=arthas

    控制台打印:name:arthas

    符合预期。

    四、小结

    arthas是一个神器,代码热修改只是它的一个小功能。它还有许多监控方面的强大的功能。

    至于它是怎么做到的,我还是继续学习字节码吧!

    五、参考

    1、https://arthas.aliyun.com/doc/quick-start.html

    2、https://blog.csdn.net/qq_27184497/article/details/118875205

    3、https://blog.csdn.net/weixin_46007214/article/details/117393545

  • 相关阅读:
    怎样打印日志
    log4j(一)
    idea没有subversion问题
    tomcat启动报异常(一)
    HashSet
    spring容器初始化bean和销毁bean之前进行一些操作的定义方法
    MyBatis中$和#的区别
    基本数据类型与引用数据类型
    Access restriction: The method 'CharacterEncoder.encode(byte[])' is not API...
    Object源码
  • 原文地址:https://www.cnblogs.com/shuimutong/p/16216070.html
Copyright © 2020-2023  润新知