java 优雅停机_spring boot2.0实现优雅停机的方法

前期踩的坑 (spring boot 1.x)

1. 添加mavne依赖

org.springframework.boot

spring-boot-starter-actuator

2. 启用shutdown

在配置文件里添加下面的配置

#启用shutdown endpoint的http访问

endpoints.shutdown.enabled=true

#不需要验证

endpoints.shutdown.sensitive=false

启动的时候可以看到下面的日志,就说明成功了

b3c3f781928e68bbd02ee41016c8c03e.png

3. 优雅停机

发送post请求 http://localhost:8080/shutdown

如果响应码是404 可以尝试post http://localhost:8080/actuator/shutdown

spring boot 2.0

如果你使用的spring boot版本是2.x的就会发现,这些post请求都会出现404的结果。

下面是spring boot 2.0 优雅停机的实现方式。

1.修改application启动类

tomcat容器

@springbootapplication

public class shutdownapplication {

public static void main(string[] args) {

springapplication.run(shutdownapplication.class, args);

}

/**

* 用于接受 shutdown 事件

*/

@bean

public gracefulshutdown gracefulshutdown() {

return new gracefulshutdown();

}

/**

* 配置tomcat

*

* @return

*/

@bean

public servletwebserverfactory servletcontainer() {

tomcatservletwebserverfactory tomcat = new tomcatservletwebserverfactory();

tomcat.addconnectorcustomizers(gracefulshutdown());

return tomcat;

}

/**

* 优雅关闭 spring boot。容器必须是 tomcat

*/

private class gracefulshutdown implements tomcatconnectorcustomizer, applicationlistener {

private final logger log = loggerfactory.getlogger(gracefulshutdown.class);

private volatile connector connector;

private final int waittime = 10;

@override

public void customize(connector connector) {

this.connector = connector;

}

@override

public void onapplicationevent(contextclosedevent contextclosedevent) {

this.connector.pause();

executor executor = this.connector.getprotocolhandler().getexecutor();

if (executor instanceof threadpoolexecutor) {

try {

threadpoolexecutor threadpoolexecutor = (threadpoolexecutor) executor;

threadpoolexecutor.shutdown();

if (!threadpoolexecutor.awaittermination(waittime, timeunit.seconds)) {

log.warn("tomcat 进程在" + waittime + " 秒内无法结束,尝试强制结束");

}

} catch (interruptedexception ex) {

thread.currentthread().interrupt();

}

}

}

}

}

undertow容器 (没有使用过,不保证可用)

@springbootapplication

public class application {

public static void main(string[] args) {

springapplication.run(application.class, args);

}

/**

* 优雅关闭 spring boot

*/

@component

public class gracefulshutdown implements applicationlistener {

@autowired

private gracefulshutdownwrapper gracefulshutdownwrapper;

@autowired

private servletwebserverapplicationcontext context;

@override

public void onapplicationevent(contextclosedevent contextclosedevent){ gracefulshutdownwrapper.getgracefulshutdownhandler().shutdown();

try {

undertowservletwebserver webserver = (undertowservletwebserver)context.getwebserver();

field field = webserver.getclass().getdeclaredfield("undertow");

field.setaccessible(true);

undertow undertow = (undertow) field.get(webserver);

list listenerinfo = undertow.getlistenerinfo();

undertow.listenerinfo listener = listenerinfo.get(0);

connectorstatistics connectorstatistics = listener.getconnectorstatistics();

while (connectorstatistics.getactiveconnections() > 0){}

}catch (exception e){

// application shutdown

}

}

}

@component

public class gracefulshutdownwrapper implements handlerwrapper{

private gracefulshutdownhandler gracefulshutdownhandler;

@override

public httphandler wrap(httphandler handler) {

if(gracefulshutdownhandler == null) {

this.gracefulshutdownhandler = new gracefulshutdownhandler(handler);

}

return gracefulshutdownhandler;

}

public gracefulshutdownhandler getgracefulshutdownhandler() {

return gracefulshutdownhandler;

}

}

@component

@allargsconstructor

public class undertowextraconfiguration {

private final gracefulshutdownwrapper gracefulshutdownwrapper;

@bean

public undertowservletwebserverfactory servletwebserverfactory() {

undertowservletwebserverfactory factory = new undertowservletwebserverfactory();

factory.adddeploymentinfocustomizers(deploymentinfo -> deploymentinfo.addouterhandlerchainwrapper(gracefulshutdownwrapper));

factory.addbuildercustomizers(builder -> builder.setserveroption(undertowoptions.enable_statistics, true));

return factory;

}

}

}

2. 使用 kill命令杀死进程

使用下面的命令杀死进程。该命令是向 某个进程发送终止信号。

kill -15 [pid]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值