别再用 kill -9 了,这才是微服务上下线的正确姿势!
点击上方“码农突围”,马上关注
这里是码农充电第一站,回复“666”,获取一份专属大礼包 真爱,请设置“星标”或点个“在看
地址:https://fredal.xin/graceful-soa-updown
优雅下线
基础下线(Spring/SpringBoot/内置容器)
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
close();
}
});
程序正常退出
使用System.exit()
终端使用Ctrl+C
使用Kill pid干掉进程
kill -9
程序肯定是不知所措的。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();
}
listeners.finished(context, null)
中,完完全全可以保证内置容器 端口已经存在了,所以我们可以监听这个事件去做优雅上线的逻辑,甚至可以把中间件相关的健康检查集成在这里。@Component
public class GracefulStartupListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent){
//注册逻辑 优雅上线
apiRegister.register(urls);
...
}
}
外置容器(Jetty)优雅上线
启动容器 -> 健康检查 -> 上线服务逻辑 -> 健康上线服务直至完成
的流程。- END - 最近热文
• 疯了!成千上万网友正自爆公司薪资待遇!!! • 985大学最美小姐姐,堪称今年最强博士后... • 0.2秒居然复制了100G文件? • 某科技公司领导称80后该退出IT行业,网友炸了!
评论