阿里巴巴Arthas實踐--jad/mc/redefine線上熱更新一條龍

背景

儘管在生產環境熱更新代碼,並不是很好的行爲,很可能導致:熱更不規範,同事兩行淚。

但很多時候我們的確希望能熱更新代碼,比如:

線上排查問題,找到修復思路了,但應用重啓之後,環境現場就變了,難以復現。怎麼驗證修復方案?

又比如:

本地開發時,發現某個開源組件有bug,希望修改驗證。如果是自己編譯開源組件再發布,流程非常的長,還不一定能編譯成功。有沒有辦法快速測試?

Arthas是阿里巴巴開源的Java應用診斷利器,深受開發者喜愛。

下面介紹利用Arthas 3.1.0版本的 jad/mc/redefine 一條龍來熱更新代碼。

  • Arthas: https://github.com/alibaba/arthas

  • jad命令: https://alibaba.github.io/arthas/jad.html

  • mc命令: https://alibaba.github.io/arthas/mc.html

  • redefine命令: https://alibaba.github.io/arthas/redefine.html

Arthas在線教程

下面通過Arthas在線教程演示熱更新代碼的過程。

  • Arthas進階教程

arthas-online-hotswap

在例子裏,訪問 curl http://localhost/user/0,會返回500錯誤:

{
    "timestamp"1550223186170,
    "status"500,
    "error""Internal Server Error",
    "exception""java.lang.IllegalArgumentException",
    "message""id < 1",
    "path""/user/0"
}

下面通過熱更新代碼,修改這個邏輯。

jad反編譯代碼

反編譯UserController,保存到 /tmp/UserController.java文件裏。

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

修改反編繹出來的代碼

用文本編輯器修改/tmp/UserController.java,把拋出異常改爲正常返回:

    @GetMapping(value={"/user/{id}"})
    public User findUserById(@PathVariable Integer id) {
        logger.info("id: {}", (Object)id);
        if (id != null && id < 1) {
            return new User(id, "name" + id);
            // throw new IllegalArgumentException("id < 1");
        }
        return new User(id.intValue(), "name" + id);
    }

sc查找加載UserController的ClassLoader

$ sc -d *UserController | grep classLoaderHash
 classLoaderHash   1be6f5c3

可以發現是spring boot的 LaunchedURLClassLoader@1be6f5c3 加載的。

mc內存編繹代碼

保存好/tmp/UserController.java之後,使用mc(Memory Compiler)命令來編譯,並且通過-c參數指定ClassLoader

$ mc -c 1be6f5c3 /tmp/UserController.java -d /tmp
Memory compiler output:
/tmp/com/example/demo/arthas/user/UserController.class
Affect(row-cnt:1) cost in 346 ms

redefine熱更新代碼

再使用redefine命令重新加載新編譯好的UserController.class

$ redefine /tmp/com/example/demo/arthas/user/UserController.class
redefine success, size: 1

檢驗熱更新結果

再次訪問 curl http://localhost/user/0,會正常返回:

{
    "id"0,
    "name""name0"
}

總結

Arthas裏 jad/mc/redefine 一條龍來線上熱更新代碼,非常強大,但也很危險,需要做好權限管理。

比如,線上應用啓動帳號是 admin,當用戶可以切換到admin,那麼

  • 用戶可以修改,獲取到應用的任意內存值(不管是否java應用)

  • 用戶可以attach jvm

  • attach jvm之後,利用jvm本身的api可以redefine class

所以:

  • 應用的安全主要靠用戶權限本身的管理

  • Arthas主要是讓jvm redefine更容易了。用戶也可以利用其它工具達到同樣的效果

最後,Arthas提醒您: 診斷千萬條,規範第一條,熱更不規範,同事兩行淚


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章