儘管在生產環境熱更新代碼,並非很好的行爲,極可能致使:熱更不規範,同事兩行淚。html
但不少時候咱們的確但願能熱更新代碼,好比:java
線上排查問題,找到修復思路了,但應用重啓以後,環境現場就變了,難以復現。怎麼驗證修復方案?git
又好比:github
本地開發時,發現某個開源組件有bug,但願修改驗證。若是是本身編譯開源組件再發布,流程很是的長,還不必定能編譯成功。有沒有辦法快速測試?spring
Arthas是阿里巴巴開源的Java應用診斷利器,深受開發者喜好。api
下面介紹利用Arthas 3.1.0版本的 jad
/mc
/redefine
一條龍來熱更新代碼。安全
下面經過Arthas在線教程演示熱更新代碼的過程。bash
在例子裏,訪問 curl http://localhost/user/0
,會返回500錯誤:app
{ "timestamp": 1550223186170, "status": 500, "error": "Internal Server Error", "exception": "java.lang.IllegalArgumentException", "message": "id < 1", "path": "/user/0" }
下面經過熱更新代碼,修改這個邏輯。curl
反編譯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 -d *UserController | grep classLoaderHash classLoaderHash 1be6f5c3
能夠發現是spring boot的 LaunchedURLClassLoader@1be6f5c3
加載的。
保存好/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命令從新加載新編譯好的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,那麼
因此:
最後,Arthas提醒您: 診斷千萬條,規範第一條,熱更不規範,同事兩行淚。
歡迎關注橫雲斷嶺的專欄,專一Java,Spring Boot,Arthas,Dubbo。