前期踩的坑 (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
启动的时候可以看到下面的日志,就说明成功了
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]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!