别再用 kill -9 了,这才是微服务上下线的正确姿势!
- 前言 -
- 优雅下线 -
基础下线(Spring/SpringBoot/内置容器)
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
close();
}
});
程序正常退出; 使用System.exit(); 终端使用Ctrl+C; 使用Kill pid干掉进程。
public void registerShutdownHook() {
if (this.shutdownHook == null) {
this.shutdownHook = new Thread() {
public void run() {
synchronized(AbstractApplicationContext.this.startupShutdownMonitor) {
AbstractApplicationContext.this.doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
public void destroy() {
this.close();
}
public void close() {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.doClose();
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
} catch (IllegalStateException var4) {
;
}
}
}
}
protected void doClose() {
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
this.publishEvent((ApplicationEvent)(new ContextClosedEvent(this)));
} catch (Throwable var3) {
this.logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", var3);
}
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
} catch (Throwable var2) {
this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);
}
}
this.destroyBeans();
this.closeBeanFactory();
this.onClose();
this.active.set(false);
}
}
@Component
public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent contextClosedEvent){
//注销逻辑
zookeeperRegistry.unregister(mCurrentServiceURL);
...
}
}
可能会有疑问的是,微服务中一般来说,注销服务往往是优雅下线的第一步,接着才会执行停机操作,那么这个时候流量进来怎么办呢?
- Docker 中的下线 -
- 外置容器的 shutdown 脚本(Jetty) -
- 优雅上线 -
springboot 内置容器优雅上线
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
healthCheckerProcessor.init();
healthIndicatorProcessor.init();
afterHealthCheckCallbackProcessor.init();
publishBeforeHealthCheckEvent();
readinessHealthCheck();
}
@Component
public class GracefulStartupListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent){
//注册逻辑 优雅上线
apiRegister.register(urls);
...
}
}
外置容器(Jetty)优雅上线
作者:fredalxin
来源:
https://fredal.xin/graceful-soa-updown
评论