Java优雅停机 @上源码

日常上线重新发布项目时需要考虑服务是否还在对外提供服务,处理请求中,尤其是一些需要调用外部服务的项目尤其需要注意(如果下游服务没有做好幂等处理时会出现重复数据等脏数据问题),Java通常是通过钩子函数处理这个问题(Runtime.getRuntime().addShutdownHook())。

一、关闭场景

1.正常关闭

1.1 非守护线程执行完毕
1.2 kill -2 \ -15 
1.3 System.exit(0)
1.4 ctl + c

2.异常关闭

2.1 RuntimeException
2.2 oom

3.强制关闭

3.1 断电
3.2 系统关机
3.3 kill -9
3.4 Runtime.halt()

二、SpringBoot优雅停机

1.使用spring-boot-starter-actuator

1.1)添加依赖【pom.xml】   

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

1.2)添加配置文件【application.yml】

management:
  server:
    port: 12345             # 端口默认=server.port 增加安全性
  endpoints:
    web:
      exposure:
        include: "*"        # 开放节点 * 开放所有 beans,.....
  endpoint:
    shutdown:
      enabled: true         # 打开shutdown端点 POST请求

1.3)CURL调用关闭接口

curl -X POST http://{ip}:{port}/actuator/shutdown

2.自己实现关闭请求接口

使用ConfigurableApplicationContext 的close方法。

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class ShutdownContext implements ApplicationContextAware {

    private ConfigurableApplicationContext context;

    public void showdown() {
        if (null != context) {
            context.close();
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (applicationContext instanceof ConfigurableApplicationContext) {
            this.context = (ConfigurableApplicationContext) applicationContext;
        }

    }
}

3.Springboot2.3开启Graceful Shutdown配置

3.1)添加配置文件【application.yml】

server:
  shutdown: graceful                 #开启优雅停机,默认是立即停机IMMEDIATE
spring:
  lifecycle:
    timeout-per-shutdown-phase: 20s  #缓冲器即最大等待时间

3.2)kill -2 \   ctl + c

三、linux kill 命令

kill -2   pid 向指定 pid 发送 SIGINT 中断信号, 等同于 ctrl+c。
kill -9   pid 向指定 pid 发送 SIGKILL 立即终止信号。
kill -15 pid 向指定 pid 发送 SIGTERM 终止信号,等同于 kill pid。

SIGINT信号【-2】:
会被当前进程树接收到,当前进程与它的子进程都会收到该信号。


SIGKILL信号【-9】:
程序不能捕获该信号,最粗暴最快速结束程序的方法。


SIGTERM信号【-15】:
会被当前进程接收到, 它的子进程不会收到, 如果当前进程被kill掉, 它的的子进程的父进程将变成init进程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值