【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...

相关推荐
努力的小郑5 分钟前
MySQL索引(三):字符串索引优化之前缀索引
后端·mysql·性能优化
IT_陈寒27 分钟前
🔥3分钟掌握JavaScript性能优化:从V8引擎原理到5个实战提速技巧
前端·人工智能·后端
程序员清风1 小时前
贝壳一面:年轻代回收频率太高,如何定位?
java·后端·面试
考虑考虑1 小时前
Java实现字节转bcd编码
java·后端·java ee
AAA修煤气灶刘哥2 小时前
ES 聚合爽到飞起!从分桶到 Java 实操,再也不用翻烂文档
后端·elasticsearch·面试
爱读源码的大都督2 小时前
Java已死?别慌,看我如何用Java手写一个Qwen Code Agent,拯救Java
java·人工智能·后端
星辰大海的精灵2 小时前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
天天摸鱼的java工程师2 小时前
RestTemplate 如何优化连接池?—— 八年 Java 开发的踩坑与优化指南
java·后端
一乐小哥3 小时前
一口气同步10年豆瓣记录———豆瓣书影音同步 Notion分享 🚀
后端·python
LSTM973 小时前
如何使用C#实现Excel和CSV互转:基于Spire.XLS for .NET的专业指南
后端