【SpringBoot系列】轻松实现线上热更新

最近一直在使用springboot做开发,sprngboot会打包成jar,和之前的实现机制略有不同。

之前在做游戏的时候热更新使用的是自己实现的机制,会打包成class ,具体的实现可以参考我之前的文章

gamwatcher.blog.csdn.net/article/det...

1、方案

springboot的热更新网上有不少资料,但是大部分都是写的开发期的热更新,这个方案对于我来说基本没用,平常开发直接ctrl + F9 热更,用不到那东西。

生产环境热更的资料不太少,也是百花齐放,没有合适的。

基于自己以往的经验,个人选择使用arthas + springboot 实现热更新。

由于现在部署环境基本上都是容器,所以下面就这些技术方案进行实现。

热更新的限制

2、热更新的局限性

热更新不是万能的,因为程序没办法重启,所以有一些事情做不了,比如:重启应用,哈哈,主要有下面几个限制。

  • 函数签名不能修改,只能修改函数内部的逻辑。
  • 不能增加或者减少类的函数或变量。
  • 函数必须能够退出,如果有函数在死循环中,无法执行更新类(笔者实验发现,死循环跳出之后,再执行类的时候,才会是更新类)

3、技术方案实现

3.1 创建一个springboot 项目

这里直接使用idea 创建一个空的springboot项目,并创建一个controller,代码实现如下

js 复制代码
package com.pdool.arthashot;  
  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  
  
/**  
* @author 种鑫  
* @date 2023/10/23 16:44  
*/  
@RestController  
public class TestController {  
  
@GetMapping("/test")  
public String sayHello(){  
return "hello arthas";  
}  
  
}

其他的配置不改

3.2 arthas环境搭建

因为要在容器中使用,所以需要搭建环境。

官方推荐的是下载arthas-boot.jar ,然后启动启动命令为

java -jar arthas-boot.jar

这个命令有个问题是每次启动的时候会去下载一堆东西,也就是说这个只是启动器。

在容器中每次下载肯定不合适,而且万一遇到没外网的环境更不能实现。必须将文件直接保存在容器内

完整的环境包下载地址:下载 离线完整包17.8M

github.com/alibaba/art...

下载后放入项目根路径

注:

在官方网站看到下面的教程,试了下不行,没有研究为什么,

arthas 教程

arthas.aliyun.com/doc/docker....

3.3 打包文件说明

dockerfile

js 复制代码
#项目所依赖的jdk镜像  
FROM openjdk:11-jdk  
RUN mkdir -p /app  
WORKDIR /app  
  
#设置时区  
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
#将maven构建好的jar添加到镜像中,第二个为别名  
COPY start.sh start.sh  
  
COPY arthas-bin.zip arthas.zip  
RUN unzip arthas.zip -d arthas-tool  
  
ADD target/arthas-hot-0.0.1-SNAPSHOT.jar arthas-hot.jar  
#暴露的端口号(和项目端口号等同)  
EXPOSE 8080  
#镜像所执行的命令  
ENTRYPOINT ["bash","start.sh"]

这里需要注意的就是将arthas拷贝到容器,然后解压到arthas-tool文件夹下

等会使用的时候可以去这个目录下

启动start.sh脚本如下

#/bin/bash java -Duser.timezone=GMT+08 -jar arthas-hot.jar

3.4 部署热更实现

将上述项目部署到服务器

这里我做了端口映射和挂载

注:使用idea部署项目到远程docker 可以看这篇文章 blog.csdn.net/perfect2011...

3.5 热更新

直接访问路径http://172.26.1.152:39002/test

可以看到结果

现在修改代码改为

js 复制代码
/**  
* @author 种鑫  
* @date 2023/10/23 16:44  
*/  
@RestController  
public class TestController {  
  
@GetMapping("/test")  
public String sayHello(){  
return "hello arthas hot";  
}  
  
}

在本地编译后,去target /classess 拷贝TestController.class

idea 中反编译可以看到class 中已经存在

将TestController.class 上传到服务器目录(映射的目录)

3.6 启动arthas

1、进入容器

docker exec -it arthas-hot bash

2、进入目录

cd arthas-tool

3、启动arthas

java -jar arthas-boot.jar

4、attach到Java

这里只有一个进程,直接选择1 就行,arthas貌似可以直接attach,没研究

5、热更代码

retransform /app/hot/TestController.class

具体的操作记录可以看下图

再次打开网页可以看到代码已经热更

4、总结

整个技术方案还是很简单的,就是使用arthas的热更功能。

使用arthas的好处就是在出现问题的时候使用,既能使用他的诊断,又能顺道热更,比自己实现的方案更靠谱

在做的过程中还是遇到一些问题的

1、arthas完整包的下载,arthas-boot.jar 每次都会下载,不知道下载什么,去到github的release下看到文件大小才猜到

2、idea中有插件可以生成arthas command,这个在使用的过程中还是有一些问题,特别是热更

3、热更代码映射出目录,方便热更class

4、当前只是完整的技术方案,如果在线上使用还需要自动化,毕竟不可能每个容器都这么做。

相关推荐
鬼火儿18 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin18 小时前
缓存三大问题及解决方案
redis·后端·缓存
间彧19 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧19 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
间彧20 小时前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧20 小时前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧20 小时前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端
间彧20 小时前
Docker Compose和Kubernetes在编排服务时有哪些核心区别?
后端
间彧20 小时前
如何在实际项目中集成Arthas Tunnel Server实现Kubernetes集群的远程诊断?
后端
brzhang20 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构