SpringBoot熱部署
-
前言
在實際開發過程中,每次修改代碼就得将項目重新開機,重新部署,對于一些大型應用來說,重新開機時間需要花費大量的時間成本。對于一個後端開發者來說,重新開機過程确實很難受啊。在 Java 開發領域,熱部署一直是一個難以解決的問題,目前的 Java 虛拟機隻能實作方法體的修改熱部署,對于整個類的結構修改,仍然需要重新開機虛拟機,對類重新加載才能完成更新操作。下面我=我們就看看對于簡單的類修改的熱部署怎麼實作。
-
原理
深層原理是使用了兩個ClassLoader,一個Classloader加載那些不會改變的類(第三方Jar包),另一個ClassLoader加載會更改的類,稱為restart ClassLoader,這樣在有代碼更改的時候,原來的restart ClassLoader 被丢棄,重新建立一個restart ClassLoader,由于需要加載的類相比較少,是以實作了較快的重新開機時間。
目前市面上最好的兩種熱部署的方式
- devtools (一般) (原理就是加快重新開機的速度而已)
- JRebel (超級推薦 ) 原理就是替換修改的檔案而已,而不是重新開機 …(熱部署成功會有提示的)
反正看情況把 推薦使用 JRebel (内網好像 不太行 …研究中) 如果能部署成功使用JRebel 如果部署不成功就使用 devtools
IDEA必須的配置
實作熱部署前必須的配置
快捷鍵: Shift+Ctrl+Alt 搜尋 Registry 點選
進行搜尋 compiler 或者 automake
然後勾選勾選 compiler.automake.allow.when.app.running 之後cloes關閉就行
配置代碼自動編譯
devtools方式
添加pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 必須設定為true 否則 devtools不生效-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
添加配置
spring:
devtools:
livereload:
enabled: false
restart:
enabled: true #設定開啟熱部署
additional-paths: src/main/java,src/main/resources #添加那個目錄的檔案需要restart
# #排除那個目錄的檔案不需要restart
# exclude: static/**,public/**
freemarker:
cache: false #頁面不加載緩存,修改即時生效
快捷鍵:Ctrl+F9 實作熱部署。
JRebel方式
Jrebel 可快速實作熱部署,節省了大量重新開機時間,提高了個人開發效率。
JRebel是一款JAVA虛拟機插件,它使得JAVA程式員能在不進行重部署的情況下,即時看到代碼的改變對一個應用程式帶來的影響。JRebel使你能即時分别看到代碼、類和資源的變化,你可以一個個地上傳而不是一次性全部部署。當程式員在開發環境中對任何一個類或者資源作出修改的時候,這個變化會直接反應在部署好的應用程式上,進而跳過了建構和部署的過程,可以省去大量的部署用的時間。
JRebel是一款JVM插件,它使得Java代碼修改後不用重新開機系統,立即生效。
IDEA上原生是不支援熱部署的,一般更新了 Java 檔案後要手動重新開機 Tomcat 伺服器,才能生效,浪費時間浪費生命。
目前對于idea熱部署最好的解決方案就是安裝JRebel插件。
親測可以實作熱部署的内容:
- 在類中新添加方法
- 修改方法參數
- 添加成員變量
- 修改方法體内代碼
-
修改 resources 下各種靜态檔案内容
如果是mapper.xml 那麼需要在application.yml配置 (否則找不到)
mybatis: type-aliases-package: com.rocketmq.pojo mapper-locations: classpath:mappers/*Mapper.xml # resources/mappers/*Mapper.xml
- 添加controller接口
- 建立類
- 添加lambda注解
不能實作熱部署:
- 新添加一個功能,但是這個功能需要添加新的jar的情況下 ,反正如果Ctrl+F9沒有效果就Ctrl+Shift+F9 如果還沒有效果那麼就重新開機就行了,一般重新開機後就可以使用Ctrl+F9進行快速熱更新了
- 有些注解修改後也不好使,…還有其他的這個都需要自己去發現…
注意: 項目所在路徑不能是中文的否則使用不了JRebel 會報錯
下載下傳 JRebel 可以在IDEA->settings->plugins搜尋
JRebel and xRebel for Intellij
然後安裝
或在IDEA插件倉庫 找到對應你目前IDEA版本的
JRebel and xRebel for Intellij
下載下傳 然後直接拉入IDEA自動安裝
然後激活:
GUID生成器:
http://jrebel.cicoding.cn/guid
伺服器位址:
http://jrebel.cicoding.cn/
先擷取到GUID生成器的碼 然後和伺服器位址進行拼接
列:
http://jrebel.cicoding.cn/EA221385-4AB5-8DE3-6C7E-640A233116EC
稍等一會…
激活成功
然後檢查是否啟動 一般都是自動啟動的
然後我們設定離線工作,不然每次啟動都要去驗證是否激活導緻IDEA啟動慢
點選work offine 就行了
如果到期了 點選 Renew offline seat … 之後在從新激活下 然後在設定離線工作 …
項目配置
配置要熱加載的項目
在啟動項目前我們需要勾選具體熱加載的項目 (注意不要全部勾選,隻勾選你正在使用的項目,不然編譯有點慢)
以上成功之後就可以通過JRebel啟動項目。
啟動方式和一起一樣 隻是都換成
第一個就是RUN 啟動 第二個就是DEBUG 啟動
每次修改代碼之後 直接 Ctrl+F9 如果修改了靜态檔案那麼 Ctrl+shift+F9 熱部署成功完成後控制台會列印
在windows 10 中如果發現端口号被占
taskkill /F /IM java.exe
還有一個問題就是如果我們使用mybatis-plus修改了mapper.xml 檔案時候不會生效 (mybatis-plus版本不要太新會出問題)
解決辦法 下載下傳
Jrebel MybatisPlus Extension
插件就行了 (修改完 xml,Jrebel 可能不會提示成功修改 xml,但是其實已經生效了)
離線版安裝 Jrebel
如果離線安裝運作jrebel時候出現下面情況,那麼就不要在使用Jrebel了這個問題是作業系統不支援你這樣弄提前把JVM給關閉了(沒辦法解決)
Jrebel 是需要借助 http://jrebel.cicoding.cn/ 服務的 但是如果在内網就需要我們自己搭建了
JrebelLicenseServerforjava.jar 的提取位址
連結:https://pan.baidu.com/s/13CnXHyV5GL2Zv3semyXG9g
提取碼:1234
我們也可以到getee 或者github 上找 JrebelLicenseServerforjava 項目 然後自己打成jar包
然後在内網有java環境的地方 使用
java -jar JrebelLicenseServerforjava.jar
啟動項目
如果是在windows上想要背景運作 那麼
start java -jar JrebelLicenseServerforjava.jar
如果是在linux 上想要背景運作那麼
java -jar JrebelLicenseServerforjava.jar &
之後激活的時候就 http://localhost:8081/44E0BBD3-8C7E-6577-D2B3-C5FA5B259BA7 就行了
注意: Jrebel服務不能關閉,否則IDEA裡使用不了熱部署了,檢視Jrebel是否能正常使用在上面已經示範了
其他配置同上就行了
可以放在公司的内網linux伺服器上一勞永逸 步驟如下,
在伺服器的/data 下建立一個腳本 shuatiapi.sh 沒有就建立一個
mkdir /data
vi /data/shuatiapi.sh
#!/bin/sh
# chkconfig: 2345 85 15
# description:auto_run
#JAR根位置
JAR_ROOT=/data/
#JAR位置
JAR_PATH="$JAR_ROOT"JrebelLicenseServerforjava.jar
#LOG位置
LOG_PATH="$JAR_ROOT"log.txt
#開始方法
start() {
cd $JAR_ROOT
nohup java -Dfile.encoding=utf-8 -jar -Xms512m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128M $JAR_PATH >$LOG_PATH &
echo "$JAR_PATH start success."
}
#結束方法
stop() {
kill -9 `ps -ef|grep $JAR_PATH|grep -v grep|grep -v stop|awk '{print $2}'`
echo "$JAR_PATH stop success."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Userage: $0 {start|stop|restart}"
exit 1
esac
然後把 JrebelLicenseServerforjava.jar 拷貝到/data目錄下
添加軟連接配接
我們可以把檔案以軟連接配接的方式放在init.d目錄中, 右側的位址相當于快捷方式
ln -s /data/shuatiapi.sh /etc/init.d/shuatiapi.sh
我們隻需要在/data下就能操作shuatiapi.sh
添加執行權限
給sh檔案和jar可執行權限
chmod +x /etc/init.d/shuatiapi.sh
chmod +x /data/JrebelLicenseServerforjava.jar
設定開機啟動
首先進入/data下,把shuatiapi.sh添加為系統服務
chkconfig --add shuatiapi.sh
開機自啟動
chkconfig shuatiapi.sh on
檢視 在最後是有我們剛才添加的 shuatiapi.sh
chkconfig --list
啟動
service shuatiapi.sh start
停用
service shuatiapi.sh stop
檢視啟動情況
lsof -i:8081
開放8081 端口
firewall-cmd --zone=public --add-port=8081/tcp --permanent
然後我們本地就可以, http://伺服器的ip:8081/44E0BBD3-8C7E-6577-D2B3-C5FA5B259BA7
比如:
http://172.30.19.35:8081/54E0BBD3-8C7E-6577-D2B3-C5FA5B259BA7
其他配置同上
使用過程出現的問題
Handler dispatch failed; nested exception is java.lang.NoSuchMethodError:
`
停用
service shuatiapi.sh stop
檢視啟動情況
lsof -i:8081
開放8081 端口
firewall-cmd --zone=public --add-port=8081/tcp --permanent
然後我們本地就可以, http://伺服器的ip:8081/44E0BBD3-8C7E-6577-D2B3-C5FA5B259BA7
比如:
http://172.30.19.35:8081/54E0BBD3-8C7E-6577-D2B3-C5FA5B259BA7
其他配置同上
使用過程出現的問題
Handler dispatch failed; nested exception is java.lang.NoSuchMethodError:
說明缺少方法 或者缺少jar包, 表示熱更新失敗 重新開機服務或者 将Maven清空然後在重新開機服務
點贊 -收藏-關注-便于以後複習和收到最新内容 有其他問題在評論區讨論-或者私信我-收到會在第一時間回複 如有侵權,請私信聯系我 感謝,配合,希望我的努力對你有幫助^_^