【SpringBoot系列】Arthas配合docker轻松实现线上热更新

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

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

《游戏系统设计三》游戏服务器线上出bug,怎么办?急,在线等!热更新_游戏服务器搭建怎么修改bug-CSDN博客

1、方案

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

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

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

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

热更新的限制

2、热更新的局限性

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

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

3、技术方案实现

3.1 创建一个springboot 项目

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

kotlin 复制代码
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

Releases · alibaba/arthas · GitHub

下载后放入项目根路径

注:

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

arthas 教程

Docker | arthas

3.3 打包文件说明

dockerfile

bash 复制代码
#项目所依赖的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脚本如下

ini 复制代码
#/bin/bash
java -Duser.timezone=GMT+08 -jar arthas-hot.jar

3.4 部署热更实现

将上述项目部署到服务器

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

注:使用idea部署项目到远程docker 可以看这篇文章 使用idea部署项目到远程docker_idea远程连接docker_香菜+的博客-CSDN博客

3.5 热更新

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

可以看到结果

现在修改代码改为

kotlin 复制代码
/**
 * @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、当前只是完整的技术方案,如果在线上使用还需要自动化,毕竟不可能每个容器都这么做。

源码下载地址:download.csdn.net/download/pe...

相关推荐
神奇小汤圆16 分钟前
浅析二叉树、B树、B+树和MySQL索引底层原理
后端
文艺理科生25 分钟前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构
千寻girling26 分钟前
主管:”人家 Node 框架都用 Nest.js 了 , 你怎么还在用 Express ?“
前端·后端·面试
南极企鹅28 分钟前
springBoot项目有几个端口
java·spring boot·后端
Luke君6079730 分钟前
Spring Flux方法总结
后端
define952733 分钟前
高版本 MySQL 驱动的 DNS 陷阱
后端
忧郁的Mr.Li1 小时前
SpringBoot中实现多数据源配置
java·spring boot·后端
暮色妖娆丶2 小时前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring
Coder_Boy_2 小时前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring
Java后端的Ai之路2 小时前
【Spring全家桶】-一文弄懂Spring Cloud Gateway
java·后端·spring cloud·gateway