(十六)優雅停機
阿新 • • 發佈:2019-02-05
dubbo的優雅停機,藉助於java虛擬機器的關閉鉤子來實現。
開啟關閉鉤子需要配置dubbo啟動引數dubbo.shutdown.hook為true,才會使用關閉鉤子啟用優雅停機。
在鉤子裡,呼叫dubbo的容器(有spring,log4j,jetty等容器,即com.alibaba.dubbo.container.Container的實現類)的stop方法,釋放相關資源。
spring在關閉時,會呼叫bean的destroy方法,dubbo的bean是擴充套件spring的,dubbo的bean會實現spring的介面DisposableBean的destroy方法:
不管是service,還是reference,都會將停機標記destroyed屬性設為true
service:
public void destroy() {
if (isDestroyed()) {
return;
}
destroyed = true;
setAvailable(false);
}
reference:
public synchronized void destroy() { if (ref == null) { return; } if (destroyed){ return; } destroyed = true; try { invoker.destroy(); } catch (Throwable t) { logger.warn("Unexpected err when destroy invoker of ReferenceConfig(" + url + ").", t); } invoker = null; ref = null; }
dubbo在呼叫服務時,會判斷服務是否已經銷燬,用一個destroyed標記來標明,下面原始碼:
com.alibaba.dubbo.rpc.protocol.AbstractInvoker<T>
public Result invoke(Invocation inv) throws RpcException { if(destroyed) { throw new RpcException("Rpc invoker for service " + this + " on consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + " is DESTROYED, can not be invoked any more!"); } //other source code... }
如果服務已經停用了,會丟擲異常,客戶端會根據配的叢集策略呼叫其他的服務。
停機時:
客戶端不再發起新的呼叫請求,新的呼叫請求都會報錯,如果還有請求未返回結果,會等待一段時間(停機超時時間),超時則強制停機;
服務端不會接收新的請求,檢查執行緒池是否還有任務未完成,有則等待一段時間(停機超時時間),超時則強制停機。
停機超時時間,dubbo預設是10秒,也可以配置指定超時時間:
# dubbo.properties
dubbo.service.shutdown.wait=10000
除了使用ShutdownHook,還可以通過呼叫:ProtocolConfig.destroyAll();
自己寫了個RPC:
可以給個star,^0^.