======
第二种方法也比较简单,获取程序启动时的上下文,然后关闭主程序启动时的上下文。这样的程序在关闭的时候也会调用PreDestroy注解。如下方法在程序启动十秒后进行关闭。
/* method 2: use ctx.close to shutdown all application context */
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
ctx.close();
第三种
===
第一种方法,在springboot启动的时候将进程号写入一个app.pid文件,生成的路径是可以指定的,可以通过命令cat /Users/huangqingshi/app.id | xargs kill命令直接停止服务,这个时候bean对象的PreDestroy方法也会调用的。这种方法大家使用的比较通用。写一个start.sh用于启动springboot程序,然后写一个停止程序将服务停止。
/* method 3 : generate a pid in a specified path, while use command to shutdown pid :
‘cat /Users/huangqingshi/app.pid | xargs kill’ */
SpringApplication application = new SpringApplication(ShutdowndemoApplication.class);
application.addListeners(new ApplicationPidFileWriter(“/Users/huangqingshi/app.pid”));
application.run();
第四种
===
第一种方法,通过调用一个SpringApplication.exit()方法也可以退出程序,同时将生成一个退出码,这个退出码可以传递给所有的上下文。这个就是一个JVM的钩子,通过调用这个方法的话会把所有PreDestroy的方法执行并停止,并传递给特定的退出码给所有上下文。通过调用System.exit(exitCode)可以将这个错误码也传给JVM。0,给JVM一个SIGNAL。
/* method 4: exit this application using static method */
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
exitApplication(ctx);
public static void exitApplication(ConfigurableApplicationContext context) {
int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
System.exit(exitCode);
}
第五种
======
第五种方法,自己写一个Controller,然后将自己编写好的Controller获取到程序的上下文,然后调用自己配置的Controller方法退出程序。通过调用自己写的/ shutDownContext方法关闭程序:curl -X POST http:// localhost:3333 / shutDownContext。
package com.hqs.springboot.shutdowndemo.controller;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author huangqingshi
* @Date 2019-08-17
*/
@RestController
public class ShutDownController implements ApplicationContextAware {
private ApplicationContext context;
@PostMapping(“/shutDownContext”)
public String shutDownContext() {
ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) context;
ctx.close();
return “context is shutdown”;
}
@GetMapping(“/”)
public String getIndex() {
return “OK”;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}
好了,springboot的优雅关闭方法也都实现好了,也有同学问,如何暴力停止呢,简单,直接kill -9相应的PID即可。
总结一下
====
以上这几种方法实现的话比较简单,但是真实工作中还需要考虑的点还很多,某些需要保护暴露的点不被别人利用,通常要加一些防火墙,或者只在内部网使用,保证程序安全。
在真实的工作中的时候第三种比较常用,程序中一般使用内存磁盘或线程池的时候最好要优雅的关机,将内存磁盘没有处理的保存起来或线程池中没处理完的程序处理完。但是因为高血压的时候比较快,所以停服务的时候最好不要处理大量的数据操作,这样会影响程序停止。
好了,大家觉得还没看全的话,可以访问我的GIT代码:
https://github.com/stonehqs/shutdowndemo.git
作者:黄青石
cnblogs.com/huangqingshi/p/11370291.html
往期精选 点击标题可跳转
Java 中什么是 IO 流,字节流、字符流两者区别,缓冲流原理代码剖析
你可能忽视的 MyBatis 3.5.X 在 JDK8 中存在的性能问题
Spring Boot 框架中使用自定义注解 + 拦截器实现身份证等敏感数据加解密
Java 中处理 Exception 的 9 种实践,曾被很多团队认可采纳,值得收藏!
Java 中 ThreadPoolExecutor 线程池必备知识点:工作流程、常见参数、性能调优及监控
MySQL 分页使用 limit 和 offset 参数为什么会导致执行变慢?
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
总目录展示
该笔记共八个节点(由浅入深),分为三大模块。
高性能。 秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。该笔记将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面重点介绍。
一致性。 秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,将用一个节点来专门讲解如何设计秒杀减库存方案。
高可用。 虽然介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,还要设计一个PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。笔记的最后,将带你思考可以从哪些环节来设计兜底方案。
篇幅有限,无法一个模块一个模块详细的展示(这些要点都收集在了这份《高并发秒杀顶级教程》里),麻烦各位转发一下(可以帮助更多的人看到哟!)
由于内容太多,这里只截取部分的内容。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算