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需要修改相应的配置,具体就不详细说了.

如果觉得文章好看,欢迎点赞.

同时欢迎关注微信公众号:氷泠之路.

IDEA/JRebel实现内部/外部/远程Tomcat热部署Spring Boot的更多相关文章

  1. IDEA连接远程服务器Docker部署Spring Boot项目

    开始前的准备工作 拥有一台云服务器,我的是腾讯云服务器(CentOS7) 腾讯云服务器安装Docker,我的版本是Docker 19.03.9,关于安装和配置镜像加速器可以查阅我的另一篇博文:http ...

  2. 持续集成环境--Tomcat热部署导致线程泄漏

    一.问题由来 我们组用jenkins部署了持续集成环境,(jenkins部署war包到远程服务器的tomcat). 每次提交了代码,jenkins上一键构建,就可以自动拉取最新代码,打war包,热部署 ...

  3. 如何修改tomcat端口以及tomcat热部署

    一.修改tomcat端口 1.首先我们需要知道,http的默认端口是80,tomcat的默认端口是8080,也就是说,如果我们将tomcat的默认端口号修改为80,输入网址的时候就可以不用输入端口了, ...

  4. tomcat源码解读(1)–tomcat热部署实现原理

    tomcat的热部署实现原理:tomcat启动的时候会有启动一个线程每隔一段时间会去判断应用中加载的类是否发生变法(类总数的变化,类的修改),如果发生了变化就会把应用的启动的线程停止掉,清除引用,并且 ...

  5. tomcat热部署,更改java类不用重新加载context

    修改类后,tomcat热部署会重新加载整个项目的context,影响开发效率.网上查的大多数是将server的modules标签中Auto Reload项改为Disabled,但是没有效果. 使用以下 ...

  6. IDEA第二章----配置git、tomcat(热部署)、database,让你的项目跑起来

    第一节:下载git客户端,整合idea 由于博主公司用的git版本管理,所以本系列都是基于git版本工具的,当然SVN与git配置类似.git同样支持安装版和解压版,支持各种操作系统,我这里下载的是W ...

  7. Tomcat 热部署

    Tomcat热部署就是实现不停机的发布项目和更新项目 1.修改conf目录下的tomcat-users.xml文件 在<tomcat-user>添加如下配置 [root@localhost ...

  8. tomcat热部署.class

    本人是在维护公司系统时遇到的问题,由于公司的系统是部署到客户服务器上,而系统中存在的问题又比较多,需要经常维护.如果每次修改完class文件后都需要去重启服务器, 那会给用户的使用造成不便,所以需要使 ...

  9. JAVAEE——宜立方商城14:项目部署规划、Tomcat热部署、反向代理的配置

    1. 学习计划 1.系统部署 2. 项目部署 2.1. 项目架构讲解 2.2. 网络拓扑图 2.3. 系统部署 2.3.1. 部署分析 e3-manager e3-manager-web e3-por ...

随机推荐

  1. 随手一记,关于Java日期时间格式化

    在Java中,我们大多数情况下格式化日期都是使用simpleDateFormat,比如把一个日期格式化成:2019-12-31的形式,我们一般定义模板为:yyyy-MM-dd的形式. 我们需要注意的是 ...

  2. 将项目加载到tomcat中的时候报错:Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules

    转自:http://jingwang0523.blog.163.com/blog/static/9090710320113294551497/ 最近在用eclipse做项目,新建项目时什么都贪新,用最 ...

  3. 基于vue3+electron11实现QQ登录切换|自定义导航栏|托盘|打包

    上一篇有给大家分享过使用vue3和electron快速搭建项目.创建多窗口/父子modal窗口的一些方法.今天继续给大家分享一些vue3.x+electron11项目开发中的一些知识点/踩坑记录,希望 ...

  4. 2021-2-26:为什么需要 System.gc() ?

    JVM 默认启动参数中,DisableExplicitGC 为 false,ExplicitGCInvokesConcurrent 为 false,对于大多数 GC (除了 ZGC 的其他 GC,包括 ...

  5. 后端程序员之路 40、Pthreads

    POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准.线程这个东西在操作系统原理里讲得比较清楚了,再加上对windows那一套进程线程的东西比较清楚,所以这里还是 ...

  6. C# 处理PPT水印(三)—— 在PPT中添加多行(平铺)文本水印效果

    在PPT幻灯片中,可通过添加形状的方式,来实现类似水印的效果,可添加单一文本水印效果,即幻灯片中只有一个文本水印:也可以添加多行(平铺)文本水印效果,即幻灯片中以一定方式平铺排列多个文本水印效果.本文 ...

  7. sqlyog如何增删改查?

    转: sqlyog如何增删改查? 下面是一道完整的 sqlyog 增删改查的练习, 顺着做下去,可以迅速掌握. 1. 创建部门表dept,并插入数据: 2. 创建emp员工表,并插入数据: sql 代 ...

  8. PAT-1147(Heaps)最大堆和最小堆的判断+构建树

    Heaps PAT-1147 #include<iostream> #include<cstring> #include<string> #include<a ...

  9. 鸿蒙的js开发模式19:鸿蒙手机下载python服务器端文件的实现

    目录:1.承接上篇鸿蒙客户端上传文件2.域名通过内网穿透工具3.python服务器端代码4.鸿蒙手机的界面和业务逻辑5.<鸿蒙的js开发模式>系列文章合集 1.承接上篇鸿蒙客户端上传文件, ...

  10. MyBatis中的Map

    接口 int addUserMap(Map<String, Object> map); Mapper.xml <!-- Map比较灵活 传递的值为Map的key,可以为任何(野路子, ...