Springboot 中 想要重启服务 该怎么写?

2022-11-14 15:20:09 +08:00
 gzk329

网上找到的方法

@SpringBootApplication
public class Application {

    private static ConfigurableApplicationContext context;

    public static void main(String[] args) {
        context = SpringApplication.run(Application.class, args);
    }

    public static void restart() {
        ApplicationArguments args = context.getBean(ApplicationArguments.class);

        Thread thread = new Thread(() -> {
            context.close();
            context = SpringApplication.run(Application.class, args.getSourceArgs());
        });

        thread.setDaemon(false);
        thread.start();
    }
}

还有是 restartEndpoint.restart();

重启结果显示无法初始化与 Mybatis-plus 相关的 bean ?

3508 次点击
所在节点    程序员
26 条回复
lower
2022-11-14 15:21:37 +08:00
调个外部脚本?
gzk329
2022-11-14 15:23:11 +08:00
@lower 不能手动 我在程序里边 调用外部脚本 脚本中把程序关了 这个脚本还会继续执行吗?
lmshl
2022-11-14 15:23:22 +08:00
System.exit() 然后等 supervisor 把自己拉起来
leipengcheng
2022-11-14 15:51:36 +08:00
mark 一下,我也有这种需求
guyeu
2022-11-14 16:09:51 +08:00
1 楼正解
pengyOne
2022-11-14 16:19:37 +08:00
@gzk329 调用外部脚本可以的。。。
gzk329
2022-11-14 16:31:25 +08:00
@pengyOne
`String[] commands = {BIN_BASH, "-c", "nohup sh restartWorker.sh"};`

```
pid=`jps -l | grep xxx | head -1 | awk '{print $1}'`
echo $pid
kill -9 $pid
while [[ $pid != "" ]]; do
echo '服务停止中...'
sleep 1
pid=`jps -l | grep xxx | head -1 | awk '{print $1}'`
done
echo '服务停止成功,开始重启服务...'
java -jar xxx.jar
```
脚本应该如何修改? 这个脚本只会 kill 不会启动
java 是用 Runtime.getRuntime().exec(commands); 执行的 shell 命令
gzk329
2022-11-14 16:32:30 +08:00
@gzk329 kill -9 和 默认的 kill -15 都试过
pengyOne
2022-11-14 16:36:25 +08:00
@gzk329 sleep 和 while 都去掉,就可以了
LiMingze
2022-11-14 16:39:33 +08:00
做成 systemd 服务就好了 重启的话直接调用 systemctl restart xxx
qhkobold
2022-11-14 17:12:15 +08:00
OldCarMan
2022-11-14 17:36:42 +08:00
@gzk329 “脚本把程序关了”,这就意味着脚本已经执行了吧,脚本本身应该不依附于程序。不过个人觉得主要的问题会不会是,把一件运维相关的事情冗余到项目里面去实现,是不是有点不妥。利用外部程序监控 Springboot 程序运行指标日志来达成重启目的是否会更好点呢?如果是业务要求,可以把相应的业务数据提供给外部程序监控,让外部程序得到重启指令。另外,重启过程的现场数据保留和数据恢复可能也是一个问题。(以上可能有理解不到位的地方,请指正)
kkkkkrua
2022-11-14 22:56:00 +08:00
参考 spring cloud 的 shutdown 接口怎么玩的
kkkkkrua
2022-11-14 23:03:11 +08:00
@kkkkkrua #13 看错了,你是重启啊
uianz
2022-11-14 23:24:21 +08:00
如果用 k8s 试试存活探针?
kwh
2022-11-14 23:32:02 +08:00
把 Spring 容器 close
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
run.close();
然后在执行一边,不就重启了吗
zhaogaz
2022-11-15 00:25:51 +08:00
做过相关的:
1. spring 有一个关闭函数,忘了你这个写的和 spring 是不是一样了。。。你发现相关的 bean 没有被管理到,,,一个思路就是改造这些 bean ,但是成本比较高。
2. 外部脚本,是能做到,大概就是写写脚本的事情。想要健壮比较麻烦,也要付出一些成本。用 java 调用 shell ,然后 shell 关闭 java ,或者是 java 自己关闭;用 shell 拉起 java
3. 简单的方法其实是包装成 docker 或者是 systemd 应用 视你当前的系统平台和能用的组件决定,也有可能是 supervisor

没啥好办法,只能这么说。。。反正得有个东西把 java 拉起来。你就想吧。
leonshaw
2022-11-15 00:34:55 +08:00
JNI 封一个 fork-exec 可行吗?
Weixiao0725
2022-11-15 00:36:36 +08:00
调用外部脚本进行 kill , 但是程序里你要捕捉到 kill -n 传进来的信号,然后把没有进行完的线程(任务)处理完,然后退出。
gzk329
2022-11-15 08:40:45 +08:00
@kwh 这个就是我上面贴的第一种方法啊 我试了 重启的时候显示无法加载与 Mybatis-plus 相关的 bean 这俩估计是有冲突

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/895138

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX