日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

JAVA熱更新

在持續(xù)交付的時代,重新部署一個新的版本只需要點擊一下按鈕。但在有的情況下,重新部署過程可能比較復(fù)雜,停機是不被允許的。所以JVM提供了另外一種選擇:在不重啟應(yīng)用的前提下進行小幅改動,又稱熱更新。

對于某些大型的應(yīng)用來說,每次的重啟都需要花費大量的時間成本,所以,如果能在不重啟虛擬機的情況下更新一個類,在某些業(yè)務(wù)場景下變得十分重要。比如很多腳本語言就支持熱替換,例如服務(wù)器端php,只要替換了PHP源文件,這種改動就會立即生效,無需重啟服務(wù)器。

在Java開發(fā)領(lǐng)域,熱更新一直是一個難以解決的問題,目前的Java虛擬機只能實現(xiàn)方法級別的熱更新,對于整個類的結(jié)構(gòu)修改,仍然需要重啟虛擬機。

熱更新的方法

Java熱更新一直不斷地改進。

1.4開始JPDA引入了hotSwap機制(JPDA Enhancements),實現(xiàn)了debug時的method body的動態(tài)性。

1.5開始通過JVMTI實現(xiàn)的java.lang.instrument(Java Platform SE 8)的premain方式,實現(xiàn)了agent方式的動態(tài)性(JVM啟動時指定agent)。

1.6增加了agentmain方式,實現(xiàn)了運行時動態(tài)性(通過The Attach API 綁定到具體VM)。其基本實現(xiàn)是通過JVMTI的retransformClass/redefineClass進行函數(shù)體級別的字節(jié)碼更新,ASM、CGLib之類基本都是圍繞這些在做動態(tài)性。

1.定義不同的classloader

在了解JVM ClassLoader之后(可以點擊查看《Java類加載及對象創(chuàng)建過程詳解》),可以通過定義不同的ClassLoader,監(jiān)聽文件變化后,通過新的ClassLoader加載新文件,然后做好相應(yīng)的狀態(tài)恢復(fù),對舊ClassLoader進行卸載等動作。(舊classloader及加載的class類在沒有實例引用的情況下,full gc時會被回收掉)

Tomcat的動態(tài)部署就是監(jiān)聽war變化,然后調(diào)用StandardContext.reload(),用新的WebContextClassLoader實例來加載war,然后初始化servlet來實現(xiàn)。類似的實現(xiàn)還有OSGi等。

這種熱更新的流程如下:

 

一文搞定Java熱更新

 

 

重新加載類的過程

2.agentmain

筆者的項目目前采用的這種形式,雖然筆者造過好多輪子,但筆者更看好Arthas這樣的開源產(chǎn)品。。。

agentmain熱更新的原理

為了實現(xiàn)Java進程A與進程B之間的本地通信,熱更新的JVM進程使用Virutalmachine.attach(pid)來連接需要熱更新的JVM進程,然后使用virtualMachine.loadAgent加載自定義的agent(筆者查看了Arthas源碼,原理也大致相同)。這個通信通道成功建立之后,那么進程A就能通知進程B去執(zhí)行某些操作,從而達到監(jiān)控進程B或者控制進程B的某些行為的目的。如jstack、jmap等JDK自帶的工具,基本都是通過Attach機制去達成各自想要的目的的。

JVM啟動的時候,在JVM內(nèi)部啟動了一個監(jiān)聽線程,這個線程的名字叫“Signal Dispatcher”,該線程的作用是,監(jiān)聽并處理OS的信號。

信號是一種進程通信。如平常我們用的最多的就是 kill -9 ${pid}來殺死某個進程,kill進程通過向${pid}的進程發(fā)送一個編號為“9”號的信號,來通知系統(tǒng)強制結(jié)束${pid}的生命周期。)

至于attach實現(xiàn),在linux下時使用文件Socket進行進程通信(對同一個文件進行讀寫操作,以達到信息的交互和共享)。

更詳細的原理,JVM大神寒泉子有篇文章《JVM源碼分析之javaagent原理完全解讀》,如點擊無法跳轉(zhuǎn),請查看筆者CSDN博客原文來點擊超鏈接。

3.Arthas

Arthas是阿里巴巴最近開源出來的一個針對java的工具,主要是針對java的問題進行診斷。

跳轉(zhuǎn)官網(wǎng)地址

這個工具可以協(xié)助完成下面這些事情(轉(zhuǎn)自官網(wǎng)):

  1. 這個類是從哪個jar包加載而來的?
  2. 為什么會報各種類相關(guān)的Exception?
  3. 線上遇到問題無法debug好蛋疼,難道只能反復(fù)通過增加System.out或通過加日志再重新發(fā)布嗎?
  4. 線上的代碼為什么沒有執(zhí)行到這里?是由于代碼沒有commit?還是搞錯了分支?
  5. 線上遇到某個用戶的數(shù)據(jù)處理有問題,但線上同樣無法 debug,線下無法重現(xiàn)。
  6. 是否有一個全局視角來查看系統(tǒng)的運行狀況?
  7. 有什么辦法可以監(jiān)控到JVM的實時運行狀態(tài)?

Arthas采用命令行交互模式,同時提供豐富的Tab自動補全功能,進一步方便進行問題的定位和診斷。

Arthas提供在線教程,相比一般的開源產(chǎn)品,上手真的很贊。

arthas實現(xiàn)熱更新

使用Arthas三個命令就可以搞定熱更新

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java
mc /tmp/UserController.java -d /tmp
redefine /tmp/com/example/demo/arthas/user/UserController.class
  1. jad命令反編譯,然后可以用其它編譯器,比如vim來修改源碼
  2. mc命令來內(nèi)存編譯修改過的代碼
  3. 用redefine命令加載新的字節(jié)碼

JVM熱更新的局限

基于Attach機制實現(xiàn)的熱更新,更新類需要與原來的類在包名,類名,修飾符上完全一致,否則在classRedefine過程中會產(chǎn)生classname don't match 的異常。

例如顯示這樣的報錯:redefineClasses exception class redefinition failed: attempted to delete a method.

具體來說,JVM熱更新局限總結(jié):

  1. 函數(shù)參數(shù)格式不能修改,只能修改函數(shù)內(nèi)部的邏輯
  2. 不能增加類的函數(shù)或變量
  3. 函數(shù)必須能夠退出,如果有函數(shù)在死循環(huán)中,無法執(zhí)行更新類(筆者實驗發(fā)現(xiàn),死循環(huán)跳出之后,再執(zhí)行類的時候,才會是更新類)

最后,限于筆者經(jīng)驗水平有限,歡迎讀者就文中的觀點提出寶貴的建議和意見。如果想獲得更多的學(xué)習(xí)資源或者想和更多的技術(shù)愛好者一起交流,可以關(guān)注我的公眾號『全菜工程師小輝』后臺回復(fù)關(guān)鍵詞領(lǐng)取學(xué)習(xí)資料、進入前后端技術(shù)交流群和程序員副業(yè)群。

分享到:
標簽:更新 Java
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定