天天看点

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清空然后在重启服务

点赞 -收藏-关注-便于以后复习和收到最新内容 有其他问题在评论区讨论-或者私信我-收到会在第一时间回复 如有侵权,请私信联系我 感谢,配合,希望我的努力对你有帮助^_^