天天看點

SpringBoot熱部署SpringBoot熱部署

SpringBoot熱部署

  1. 前言

    在實際開發過程中,每次修改代碼就得将項目重新開機,重新部署,對于一些大型應用來說,重新開機時間需要花費大量的時間成本。對于一個後端開發者來說,重新開機過程确實很難受啊。在 Java 開發領域,熱部署一直是一個難以解決的問題,目前的 Java 虛拟機隻能實作方法體的修改熱部署,對于整個類的結構修改,仍然需要重新開機虛拟機,對類重新加載才能完成更新操作。下面我=我們就看看對于簡單的類修改的熱部署怎麼實作。

  2. 原理

    深層原理是使用了兩個ClassLoader,一個Classloader加載那些不會改變的類(第三方Jar包),另一個ClassLoader加載會更改的類,稱為restart ClassLoader,這樣在有代碼更改的時候,原來的restart ClassLoader 被丢棄,重新建立一個restart ClassLoader,由于需要加載的類相比較少,是以實作了較快的重新開機時間。

目前市面上最好的兩種熱部署的方式

  1. devtools (一般) (原理就是加快重新開機的速度而已)
  2. JRebel (超級推薦 ) 原理就是替換修改的檔案而已,而不是重新開機 …(熱部署成功會有提示的)

反正看情況把 推薦使用 JRebel (内網好像 不太行 …研究中) 如果能部署成功使用JRebel 如果部署不成功就使用 devtools

IDEA必須的配置

實作熱部署前必須的配置

快捷鍵: Shift+Ctrl+Alt 搜尋 Registry 點選

SpringBoot熱部署SpringBoot熱部署

進行搜尋 compiler 或者 automake

然後勾選勾選 compiler.automake.allow.when.app.running 之後cloes關閉就行

SpringBoot熱部署SpringBoot熱部署

配置代碼自動編譯

SpringBoot熱部署SpringBoot熱部署

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插件。

親測可以實作熱部署的内容:

  1. 在類中新添加方法
  2. 修改方法參數
  3. 添加成員變量
  4. 修改方法體内代碼
  5. 修改 resources 下各種靜态檔案内容

    如果是mapper.xml 那麼需要在application.yml配置 (否則找不到)

    mybatis:
      type-aliases-package: com.rocketmq.pojo
      mapper-locations: classpath:mappers/*Mapper.xml # resources/mappers/*Mapper.xml
               
  6. 添加controller接口
  7. 建立類
  8. 添加lambda注解

不能實作熱部署:

  1. 新添加一個功能,但是這個功能需要添加新的jar的情況下 ,反正如果Ctrl+F9沒有效果就Ctrl+Shift+F9 如果還沒有效果那麼就重新開機就行了,一般重新開機後就可以使用Ctrl+F9進行快速熱更新了
  2. 有些注解修改後也不好使,…還有其他的這個都需要自己去發現…

注意: 項目所在路徑不能是中文的否則使用不了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

SpringBoot熱部署SpringBoot熱部署
SpringBoot熱部署SpringBoot熱部署

稍等一會…

激活成功

SpringBoot熱部署SpringBoot熱部署

然後檢查是否啟動 一般都是自動啟動的

SpringBoot熱部署SpringBoot熱部署

然後我們設定離線工作,不然每次啟動都要去驗證是否激活導緻IDEA啟動慢

點選work offine 就行了

SpringBoot熱部署SpringBoot熱部署

如果到期了 點選 Renew offline seat … 之後在從新激活下 然後在設定離線工作 …

項目配置

配置要熱加載的項目

SpringBoot熱部署SpringBoot熱部署

在啟動項目前我們需要勾選具體熱加載的項目 (注意不要全部勾選,隻勾選你正在使用的項目,不然編譯有點慢)

SpringBoot熱部署SpringBoot熱部署

以上成功之後就可以通過JRebel啟動項目。

啟動方式和一起一樣 隻是都換成

SpringBoot熱部署SpringBoot熱部署

第一個就是RUN 啟動 第二個就是DEBUG 啟動

SpringBoot熱部署SpringBoot熱部署

每次修改代碼之後 直接 Ctrl+F9 如果修改了靜态檔案那麼 Ctrl+shift+F9 熱部署成功完成後控制台會列印

SpringBoot熱部署SpringBoot熱部署

在windows 10 中如果發現端口号被占

taskkill /F /IM java.exe 
           

還有一個問題就是如果我們使用mybatis-plus修改了mapper.xml 檔案時候不會生效 (mybatis-plus版本不要太新會出問題)

解決辦法 下載下傳

Jrebel MybatisPlus Extension

插件就行了 (修改完 xml,Jrebel 可能不會提示成功修改 xml,但是其實已經生效了)

離線版安裝 Jrebel

如果離線安裝運作jrebel時候出現下面情況,那麼就不要在使用Jrebel了這個問題是作業系統不支援你這樣弄提前把JVM給關閉了(沒辦法解決)

SpringBoot熱部署SpringBoot熱部署

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清空然後在重新開機服務

點贊 -收藏-關注-便于以後複習和收到最新内容 有其他問題在評論區讨論-或者私信我-收到會在第一時間回複 如有侵權,請私信聯系我 感謝,配合,希望我的努力對你有幫助^_^