1 概述
所謂熱部署,對於Java應用程序來說,就是在運行時更新Java類文件.IDEA可以使用自帶的Spring Boot熱部署的方式進行本地/遠程熱部署,或者使用JRebel進行本地/遠程熱部署,不過需要安裝JRebel and XRebel for IntelliJ這個插件.本文將會介紹這兩種方式來進行熱部署,這應該是網上能找到的最詳細的IDEA熱部署的文章,相信在看完之后,開發效率會大大提升,不再需要像以前那樣手動打jar/war包然后上傳到服務器等一系列繁瑣操作.
2 環境
- IDE:IntelliJ IDEA 2019.3.1
- 本地Tomcat:9.0.30
- JRebel and XRebel for IntelliJ:2020.2.0
- 服務器:CentOS 8.1.1911
- 服務器Tomcat:9.0.33
3 IDEA熱部署
3.1 工程部分
3.1.1 新建工程
這里新建一個Spring Boot工程來進行熱部署的測試.
打包方式改為war,因為后面要使用外部Tomcat:
勾上熱部署工具Spring Boot DevTools與使用內嵌Tomcat的Spring Web.
3.1.2 測試文件
新建一個響應Get請求的Controller:
這里添加了一個控制台信息方便查看.
3.2 內部Tomcat熱部署
Spring Boot內嵌了一個Tomcat,可以直接使用其進行熱部署.
3.2.1 IDEA設置
首先需要開啟Compiler中的Build project automatically:
然后按兩下shift,切換到Action,搜索Registry:
把compiler.automake.allow.when.app.running開啟:
最后編輯運行設置:
以下兩項選擇Update classed and resources:
3.2.2 測試
IDEA自帶了一個HTTP client(其實是一個插件,不需要可以關閉),可以發送HTTP請求,新建一個HTTP Request:
名字隨便:
添加一個GET請求:
修改路徑與端口,注意路徑對應:
切換回Spring Boot的運行設置,shift+F10運行:
然后就可以發送HTTP請求了,點擊一下綠色的小三角:
返回了對應信息,控制台也有對應輸出:
然后修改Controller里面的test,改為test1:
不用重新運行項目,切換一下窗口讓IDEA進行Update操作:
控制台會重新打印Spring字樣,Messages中會看到Build completed successfully的信息,表示Update操作成功.
重新發送原來的HTTP請求,報錯:
因為此時已經沒有響應localhost:8080/test的方法了,改為test1后:
3.3 外部Tomcat熱部署
由於已經配置好了IDEA的相關設置,這里就不重復了,沒配置的按上面的方式配置,然后需要增加一個外部的Tomcat配置.
3.3.1 外部Tomcat配置
需要增加一個外部Tomcat的運行配置:
添加Tomcat,選擇local:
沒有顯示Tomcat的話在more items這里.
改個名字,Configure選擇本地Tomcat的路徑,同時把下面的Build去掉.
部署這里要選擇exploded的:
改回根路徑:
回到Server選項卡,修改以下兩項為Update classed and resources:
3.3.2 測試
注意外部的Tomcat熱部署不能使用Run運行,不能像內部的一樣直接Shift+F10,要使用Debug運行,Shift+F9:
需要確保默認的8080端口不被占用,先把剛才的Spring Boot應用暫停,在run這里,Tomcat在services這里.
測試文件還是剛才的test1,發送請求:
然后修改test1的方法體:
切換窗口后會提示class reloaded:
再次發送剛才的HTTP請求:
成功!
不過,這種熱部署只能修改方法體,如果增加了一個方法或者修改了原來的方法名等,會提示熱交換失敗,虛擬機不支持該操作:
去萬能的百度查了一下:
說是Java HotSwap的限制,HotSwap是一個JVM補丁,這里就略過了.同時后面提到一些類似JRebel的第三方工具可以支持這種類型的修改,當然,下面會有詳細介紹.
3.4 遠程Tomcat熱部署
遠程Tomcat熱部署比較麻煩,細節很多,一個端口錯誤就一堆異常,所以請耐心細看.需要三個步驟:設置服務器的Tomcat,設置IDEA的服務器配置,設置IDEA的Tomcat運行配置.最后進行測試.
3.4.1 服務器的Tomcat設置
需要處理四個端口:Tomcat的HTTP端口,JMX端口,RMI端口與調試端口.
其中HTTP端口就是常說的Tomcat端口,瀏覽器輸入http://ip:port就可以訪問到Tomcat的默認首頁,在server.xml中設置,這里的是在69行的位置,使用默認的8080.
在Tomcat的bin目錄下新建一個setenv.sh:
CATALINA_OPTS="-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8888
-Dcom.sun.management.jmxremote.rmi.port=8888
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=ip
-agentlib:jdwp=transport=dt_socket,address=0.0.0.0:12345,suspend=n,server=y"
其中JMX與RMI端口設為一致,只要沒有占用隨便取即可,address后面的12345是調試端口,根據需要設置即可.ip是服務器的ip地址
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
這兩行表示不使用ssl連接與使用JMX客戶端連接到Tomcat時不需要認證.
注意要加上
-Dcom.sun.management.jmxremote.rmi.port=8888
這個RMI端口,很多文章都沒有加上這個導致部署失敗.
最后修改執行權限並啟動tomcat:
chmod 750 setenv.sh
./startup.sh
可以查看一下端口監聽:
netstart -ano | grep -E "8080|8888|12345"
三個端口都監聽到了,表示配置成功,若沒有監聽到這三個端口,請檢查Tomcat日志.
同時注意防火牆與安全組的問題,如果開啟了防火牆請允許這三個端口通過,安全組也要開啟對應端口規則.
3.4.2 IDEA中的服務器設置
新建一個SFTP部署:
ip為服務器ip,port為ssh端口,認證方式可以密碼或者密鑰,按需要選擇,Root path設為tomcat的webapps路徑,如果有亂碼問題把下面的高級選項的編碼改為utf-8.
設置好了以后測試一下.
映射:下面有完整的說明,Local path是本地的項目路徑,Deployment path是相對與webapps的路徑(上面設置了Root path為webapps),Web path是相對與url的路徑.
3.4.3 IDEA中的Tomcat設置
新建一個Tomcat Remote:
這里是最重要的設置,設置JMX端口(這里是上面3.4.1設置的8888),Host選擇上一步創建的服務器,Path from root為根路徑,Mapped as為webapps路徑,Host下面的端口為TomcatHTTP端口(這里使用默認的8080,3.4.1中的配置有詳細說明).
部署這里選擇exploded的war包,Application context選擇根路徑.
Debug這里修改3.4.1中設置的端口:
3.4.4 測試
需要以Debug模式(Shift+F9)運行,不能直接Run(Shift+F10):
首先會提示連接到服務器和虛擬機:
然后提示成功部署:
這時候應該會自動打開瀏覽器,因為這里設置了運行后打開該URL:
修改方法體后按Ctrl+F9,提示重新加載類:
Debug信息提示已重新加載類:
這樣就熱部署成功了.
當然,像上面的使用外部Tomcat一樣,如果修改方法名或者增加方法,會提示虛擬機不支持操作(解決方法是使用下面的JRebel):
4 JRebel熱部署
4.1 JRebel簡介
JRebel是一個集成了應用服務器的JVM代理,可以使用現有的類加載器重新加載類.只有修改后的類會在運行中的應用程序被重新編譯和即時重新加載.
4.2 安裝
從設置中的Plugins安裝,搜索即可:
如果速度慢的話可以從官網(戳這里)去下載,然后從本地安裝:
4.3 內部Tomcat熱部署
內部Tocmat熱部署非常簡單,選中SpringBoot的運行配置以后,直接點擊Rebel Run即可:
控制台提示重新加載類並且重新配置bean,表示成功.
當然這樣做的前提是默認的Spring Boot配置已經像上面的3.2一樣配置好,比如如果修改為:
這樣JRebel就會沒有效果.
4.4 外部Tomcat熱部署
像上面的3.3一樣配置好外部Tomcat后,也是直接一鍵Rebel Run即可.
注意保證端口不被占用.
這里與默認的熱部署相比,最大的不同是允許增加與改變方法,而不僅僅是修改方法體(不然的話也不會出現3.3的那個問題).
下面是原來的Controller中的方法:
添加一個方法后:
提示已重新加載,表示成功,而不是提示Operation not supported by VM.
4.5 遠程Tomcat熱部署
使用JRebel進行的遠程Tomcat熱部署需要先打包上傳,然后才能熱部署.
4.5.1 打包上傳
熱部署之前,需要先手動打包:
上傳到服務器的Tomcat的webapps下.
4.5.2 新建腳本
選擇運行在遠程服務器或虛擬機,然后選擇Tomcat:
按提示新建腳本:
實測還需要修改腳本權限,750:
啟動之后可以看到JRebel的輸出:JRebel started in remote server mode:
這樣就能成功監控到變化了.
4.5.3 添加遠程服務器
服務器名字隨便,URL為ip+端口(注意服務器的防火牆還有安全組規則開放端口),如果設置了服務器認證(通過
java -jar xxx.jar -set-remote-password PASSWORD
設置),則需要勾選Server authentication並填上密碼.
如果Tomcat設置了訪問密碼(設置方法這里查看),則需要勾選HTTP Basic authentication,並填上用戶名與密碼:
測試一下連接:
沒問題就下一步.
4.5.4 測試
然后,打開JRebel,選擇部署的項目:
下面是打包時的Controller方法,只有一個test:
測試(注意test前的路徑為打包的名字,要對應):
然后加上test1方法,ctrl+F9,構建:
服務器端提示重新加載類:
再次輸入test1:
這樣就遠程熱部署成功了!
5 附錄:jar打包
由於Spring Boot內嵌了Tomcat,可以打成jar包的形式使用內嵌的Tomcat,這樣,可以避免一系列的包括目錄映射,端口等繁瑣的Tomcat配置.在原來的war打包形式的基礎上,修改pom.xml中的<packing>:
加上maven插件(默認已加上):
可以把原來的ServletInitializer刪去:
使用Maven打包:
可以先在本地測試一下:
java -jar demo.jar
沒問題的話就可以上傳到服務器了,或者直接使用熱部署,注意Tomcat與JRebel需要修改相應的配置,具體就不詳細說了.
如果覺得文章好看,歡迎點贊.
同時歡迎關注微信公眾號:氷泠之路.