Spring Boot(十三):实现热部署
一、前言
在实际开发过程中,每次修改代码就得将项目重启,重新部署,对于一些大型应用来说,重启时间需要花费大量的时间成本。对于一个后端开发者来说,重启过程确实很难受。在java开发领域,热部署一直是一个难以解决的问题,目前的java虚拟机只能实现方法体的热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作。
二、原理
深层原理是使用了两个ClassLoader,一个ClassLoader加载那些不会改变的类(第三方jar包),另一个ClassLoader加载会改变的类,称为restart ClassLoader,这样在有代码更改的时候,原来的restart ClassLoader被丢弃,重新创建一个restart ClassLoader,由于需要加载的类相对少,所以实现了较快的重启时间。
三、springboot实现热部署的三种方式
(一)Spring Loaded
Spring Loaded是一个用于在JVM运行时重新加载类文件更改的JVM代理,Spring Loaded允许你动态的新增、修改、删除某个方法、字段、构造方法,同样可以修改作用在类、方法、字段、构造方法上的注解,也可以新增、删除、改变枚举中的值。
Spring Loaded有两种实现方式,分别是Maven引入依赖方式和添加启动参数方式。
1、Maven引入依赖方式
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.6.RELEASE</version> </dependency> </dependencies> </plugin>
如果你也是IDEA的话,直接界面上双击运行即可,如下
出现如下配置表是配置成功:
[INFO] Attaching agents: [C:\Users\tengj\.m2\repository\org\springframework\springloaded\1.2.6.RELEASE\springloaded-1.2.6.RELEASE.jar]
2、添加启动参数方式
这种方式是右键运行启动类
首先先下载对应的springloaded-1.2.6.RELEASE.jar,可以去上面提到的官网获取
博主这里直接引用maven依赖已经下载好的路径哈
然后打开下图所示的Edit Configurations配置,在VM options中输入:
-javaagent:C:\Users\tengj\.m2\repository\org\springframework\springloaded\1.2.6.RELEASE\springloaded-1.2.6.RELEASE.jar -noverify
然后直接右键运行启动类即可启动项目。
上面2种方式小伙伴随便选择一种即可,当系统通过 mvn spring-boot:run启动或者 右键application debug启动Java文件时, 系统会监视classes文件,当有classes文件被改动时,系统会重新加载类文件,不用重启服务。
idea中需要重新编译文件Ctrl+Shift+F9或者编译项目Ctrl+F9。
如何测试热部署是否可用呢,你可以先写个简单的Controller方法,返回个字符串,然后启动项目,接着修改下这个方法返回的字符串,Ctrl+Shift+F9编译下当前类,然后再刷新下页面看看是否内容改变了。
在 Spring Boot,模板引擎的页面默认是开启缓存,如果修改页面内容,刷新页面是无法获取修改后的页面内容,所以,如果我们不需要模板引擎的缓存,可以进行关闭。
spring.freemarker.cache=false spring.thymeleaf.cache=false spring.velocity.cache=false
经过博主简单的测试,发现大多数情况可以使用热部署,有效的解决了文章头部中提到的那个痛点,不过还是有一些情况下需要重新启动,不可用的情况如下:
(1)对于一些第三方的注解修改不能自动加载,比如spring mvc的@RequestMapping
(2)application.properties的修改也不行
(3)log4j的配置文件的修改不能即时生效
(二)spring-boot-devtools实现热部署
spring-boot-devtools 为应用提供一些开发时特性,包括默认值设置,自动重启,livereload等。
1、pom依赖
想要使用devtools热部署功能,maven添加依赖如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
将依赖关系标记为可选<optional>true</optional>是一种最佳做法,可以防止使用项目将devtools传递性地应用于其他模块。
2、默认属性
在spring boot继承thymeleaf时,spring.thymefeaf.cache属性设置为false可以禁用模板引擎编译的缓存结果。
现在,devtools会自动帮你做到这些,禁用所有模板的缓存,包括 Thymeleaf, Freemarker, Groovy Templates, Velocity, Mustache等。
3、自动重启
自动重启的原理在于spring boot使用两个classloader:不改变的类(如第三方jar)由base类加载器加载,正在开发的类由restart类加载器加载。应用重启时,restart类加载器被扔掉重建, 而base类加载器不变,这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为base类加载器已经可用并已填充。
所以,当我们开启devtools后,classpath中的文件变化会导致应用自动重启。
当然不同的IDE效果不一样,eclipse中保存文件即可引起classpath更新,从而触发重启。而idea则需要自己手动Ctrl+F9重新编译一下。
(1)排除静态资源文件
静态资源文件在改变之后有时候没必要触发应用程序重启,例如thymeleaf模板文件就可以实时编辑,默认情况下,更改 /META-INF/maven, /META-INF/resources ,/resources ,/static ,/public 或/templates下 的资源不会触发重启,而是触发live reload(devtools内嵌了一个liveReload server,当资源发生改变时,浏览器刷新,下面会介绍)。
可以使用spring.devtools.restart.exclude属性配置,例如
spring.devtools.restart.exclude=static/**,public/**
如果想保留默认配置,同时增加新的配置,则可使用
spring.devtools.restart.additional-exclude属性
(2)观察额外的路径
如果你想观察不在classpath中的路径的文件变化并触发重启,则可以配置 spring.devtools.restart.additional-paths 属性。
不在classpath内的path可以配置spring.devtools.restart.additionalpaths属性来增加到监视中,同时配置spring.devtools.restart.exclude可以选择这些path的变化是导致restart还是live reload。
(3)关闭自动重启
设置 spring.devtools.restart.enabled 属性为false,可以关闭该特性。可以在application.properties中设置,也可以通过设置环境变量的方式。
public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); }
(4)使用一个触发条件
若不想每次修改都触发自动重启,可以设置spring.devtools.restart.trigger-file指向某个文件,只有更改这个文件时才触发自动重启。
(5)自定义自动重启类加载器
默认情况下,IDE中打开的项目都会由restart加载器加载,jar文件由base加载器加载,但是若你使用multi-module的项目,并且不是所有模块都被导入IDE中,此时会导致加载器不一致。这时你可以创建 META-INF/spring-devtools.properties文件, 并增加 restart.exclude.XXX,restart.include.XXX来配置哪些jar被restart加载,哪些被base加载。如:
restart.include.companycommonlibs=/mycorp-common-[\\w-]+\.jar restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
4、LiveReload
DevTools内置了一个LiveReload服务,可以在资源变化时用来触发浏览器刷新。当然这个需要你浏览器安装了LiveReload插件,并且启动这个插件才行。
先去谷歌商店安装LiveReload插件,自己准备梯子。
安装好在要自动刷新的页面点击下图中图标,启动应用后更新页面内容或者css等都会触发页面自动刷新了。
最后展示效果,修改完html页面后,Ctrl+Shift+F9,没有重启,页面也会自动刷新了,太有趣了。
如果您不想在应用程序运行时启动LiveReload服务器,则可以将spring.devtools.livereload.enabled属性设置为false。
一次只能运行一个LiveReload服务器。开始应用程序之前,请确保没有其他LiveReload服务器正在运行。
如果你的IDE启动多个应用程序,则只有第一个应用程序将支持LiveReload。
(三)JRebel插件方式
在IDEA中打开插件管理界面,按照下面的提示先安装上
安装完插件后,需要去获取正版的激活码,这个可以直接去官网https://my.jrebel.com获取(需自备梯子)
1、 通过fackbook登录,没有就去注册一个
2、 填写一些资料后(资料必须填写完整,否则JRebel激活不了),复制激活码即可
3、重启IDEA后,在IDEA的setting中找到JRebel输入复制的激活码即可
出现绿色,即表示激活成功了。
4、 接着就如下所示,勾中JRebel方式后启动即可,即可享受JRebel带来的超爽体验
每一篇博客都是一种经历,程序猿生涯的痕迹,知识改变命运,命运要由自己掌控,愿你游历半生,归来仍是少年。
欲速则不达,欲达则欲速!
更多精彩内容,首发公众号【素小暖】,欢迎关注。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
【云栖号案例 | 教育】TimingApp
云栖号案例库:【点击查看更多上云案例】不知道怎么上云?看云栖号案例库,了解不同行业不同发展阶段的上云方案,助力你上云决策! 公司介绍 公司地址:武汉东湖新技术开发区光谷大道41号现代·国际设计城一期3栋24层01、02号行业分布:文化案例分类:在线教育 业务痛点 TimingApp未设置专职运维人员,此前采用单体PHP架构,无法满足快速增长的业务需求。今年,开始尝试开源项目,自建微服务架+APM,但因技术门槛和人力不足一直没有成功落地。业务本身具有潮汐特性,用户访问主要集中在晚间和节假日,此外,受疫情影响,春节期间峰值流量暴增4倍,面临快速响应和成本上的压力。痛点综述:代码耦合度较高、微服务架构运维复杂、开发迭代效率较低、资源利用率不高 解决方案 解决方案逻辑图 方案细节阿里云Serverless应用引擎(简称SAE)基于Serverless架构,屏蔽了底层IaaS运维和K8s细节,区别于FaaS形态的Serverless产品,用户无需修改编程模型,零代码改造就能直接使用。同时,完美结合SpringCloud/Duboo等微服务架构,提供应用发布、管理和服务治理等应用全生命周期的服务。...
- 下一篇
如何同步OSS Bucket数据到云存储网关SMB/NFS共享
背景 云存储网关支持通过文件协议NFS/SMB来访问OSS Bucket里面的数据,用户通过创建NFS/SMB共享并绑定OSS Bucket从而实现以文件协议对OSS Bucket进行操作和管理。为了访问网关共享对应的OSS Bucket里面的存量数据,或者想获取到OSS Bucket里面新增加的文件的话,就需要将OSS Bucket里面的数据同步到云存储网关的共享里面。云存储网关主要提供了反向同步和极速同步两种方法来同步OSS Bucket里面的数据到网关侧的共享里。本文将对这两种数据同步的方法均做下介绍,给出它们的实现原理以及分别适用的场景。 反向同步 首先是反向同步的功能,这个是网关从公测开始就有的功能。用户可以在创建共享的时候打开反向同步功能或者通过共享设置页面动态的打开关闭这个功能。 和反向同步功能相关的一个非常重要的参数就是“反向同步时间间隔”。假设反向同步的时间间隔是10s,它的含义是说在用户访问某个文件夹或者它下面的某个文件时,网关会检查这个文件夹的同步时间,如果发现这个文件夹已经有超过10s没有同步了,则会从OSS里面同步一次该文件夹的内容,并更新该文件夹的同步时间。...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装