別再用 kill -9 了,這才是微服務(wù)上下線的正確姿勢(shì)!
點(diǎn)擊上方“碼農(nóng)突圍”,馬上關(guān)注
這里是碼農(nóng)充電第一站,回復(fù)“666”,獲取一份專屬大禮包 真愛(ài),請(qǐng)?jiān)O(shè)置“星標(biāo)”或點(diǎn)個(gè)“在看

地址:https://fredal.xin/graceful-soa-updown
優(yōu)雅下線
基礎(chǔ)下線(Spring/SpringBoot/內(nèi)置容器)
Runtime.getRuntime().addShutdownHook(new?Thread()?{
????@Override
????public?void?run()?{
????????close();
????}
});
程序正常退出
使用System.exit()
終端使用Ctrl+C
使用Kill pid干掉進(jìn)程
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){
???????//注銷(xiāo)邏輯
???????zookeeperRegistry.unregister(mCurrentServiceURL);
???????...
????}
}
Docker中的下線
外置容器的shutdown腳本(Jetty)
發(fā)起下線服務(wù) -> 關(guān)閉端口 -> 檢查下線服務(wù)直至完成 -> 關(guān)閉容器的流程。
優(yōu)雅上線
springboot內(nèi)置容器優(yōu)雅上線
@Override
public?void?onApplicationEvent(ContextRefreshedEvent?event)?{
????healthCheckerProcessor.init();
????healthIndicatorProcessor.init();
????afterHealthCheckCallbackProcessor.init();
????publishBeforeHealthCheckEvent();
????readinessHealthCheck();
}
listeners.finished(context, null)中,完完全全可以保證內(nèi)置容器 端口已經(jīng)存在了,所以我們可以監(jiān)聽(tīng)這個(gè)事件去做優(yōu)雅上線的邏輯,甚至可以把中間件相關(guān)的健康檢查集成在這里。@Component
public?class?GracefulStartupListener?implements?ApplicationListener<ApplicationReadyEvent>?{????
????@Override
????public?void?onApplicationEvent(ApplicationReadyEvent?applicationReadyEvent){
???????//注冊(cè)邏輯?優(yōu)雅上線
???????apiRegister.register(urls);
???????...
????}
}
外置容器(Jetty)優(yōu)雅上線
啟動(dòng)容器 -> 健康檢查 -> 上線服務(wù)邏輯 -> 健康上線服務(wù)直至完成 的流程。
-?END - 最近熱文
? ?瘋了!成千上萬(wàn)網(wǎng)友正自爆公司薪資待遇?。?! ? ?985大學(xué)最美小姐姐,堪稱今年最強(qiáng)博士后... ? ?0.2秒居然復(fù)制了100G文件? ? ?某科技公司領(lǐng)導(dǎo)稱80后該退出IT行業(yè),網(wǎng)友炸了!
評(píng)論
圖片
表情
