目錄
1 dubbo優雅停機概述
2 dubbo優雅停機實現
2.1 abstractregistryfactory.destroyall
2.1.1 registry.destroy(zookeeperregistry):
2.1.2 registry.destroy(failbackregistry)
2.1.3 通用destroy
2.2 protocol.destroy
2.2.1 registryprotocol.destroy
2.2.2 dubboprotocol.destroy
優雅停機主要應用於線上服務版本迭代的過程。如果老版本服務沒有正常關閉的話會造成記憶體清理問題。
dubbo優雅停機的實現依賴於jdk的shutdownhook方法,這個方法在如下場景會被呼叫
在abstractconfig中的靜態**塊新增了shutdowndownhook機制
static
protocolconfig.destroyall();
}}, "dubboshutdownhook"));
}public static void destroyall()
// 關閉並清理註冊中心
abstractregistryfactory.destroyall();
extensionloaderloader = extensionloader.getextensionloader(protocol.class);
for (string protocolname : loader.getloadedextensions())
} catch (throwable t)
}}
public static void destroyall()
// 加鎖,防止關閉多次
lock.lock();
try catch (throwable e)
}registries.clear();
} finally
}
public void destroy() catch (exception e)
}
public void destroy()
// 首先要明白failbackregistry的核心就在於失敗重試,所以這一層的關閉只要關閉retryfuture就可以
super.destroy();
try catch (throwable t)
}
梳理一下abstractregistryfactory.destroyall方法(沒有先後順序關係):public void destroy()
if (logger.isinfoenabled())
// 移除記憶體中已經註冊的服務
setdestroyregistered = new hashset(getregistered());
if (!destroyregistered.isempty())
} catch (throwable t) }}
}// 取消所有的服務訂閱
map> destroysubscribed = new hashmap>(getsubscribed());
if (!destroysubscribed.isempty())
} catch (throwable t) }}
}}
1 關閉zk客戶端
2 由於服務註冊zk的時候建立的臨時節點,這些臨時節點也會刪除
3 關閉retryfuture
4 移除記憶體中已經註冊的服務
5 取消所有的服務訂閱
protocol的實現類中主要有兩個,registryprotocol和dubboprotocol
dubboexporter.unexportpublic void destroy()
bounds.clear();
}
public void unexport()
abstractexporter.unexport
dubboinvoker.destroypublic void unexport()
unexported = true;
getinvoker().destroy();
}
註冊協議只關心跟註冊有關的內容,而exporter和invoker都是registryprotocol下層的內容,所以在呼叫註冊協議關閉服務的時候會將其下的exporter和invoker都關閉掉。public void destroy() else
// 關閉invoker和exchange
super.destroy();
if (invokers != null)
for (exchangeclient client : clients) catch (throwable t)
}} finally
}}
梳理一下protocol.destroy流程public void destroy()
// headerexchangeserver中會停止傳送心態的任務,關閉channel
server.close(getservershutdowntimeout());
} catch (throwable t) }}
//關停所有的client,作為consumer將不再傳送新的請求
for (string key : new arraylist(referenceclientmap.keyset()))
// headerexchangeclient中會停止傳送心態的任務,關閉channel
client.close(getservershutdowntimeout());
} catch (throwable t) }}
//對於幽靈客戶端的處理邏輯暫時先忽略
for (string key : new arraylist(ghostclientmap.keyset()))
client.close(getservershutdowntimeout());
} catch (throwable t) }}
stubservicemethodsmap.clear();
super.destroy();
}
1 把記憶體中的export移除
2 關閉registryprotocol管理的invoker和exchange
3 關停所有的server,作為provider將不再接收新的請求
4 關停所有的client,作為consumer將不再傳送新的請求
Dubbo 優雅停機
對於任何乙個線上應用,如何在服務更新部署過程中保證客戶端無感知是開發者必須要解決的問題,即從應用停止到重啟恢復服務這個階段不能影響正常的業務請求。理想條件下,在沒有請求的時候再進行更新是最安全可靠的,然而網際網路應用必須要保證可用性,因此在技術層面上優化應用更新流程來保證服務在更新時無損是必要的。傳...
Dubbo優雅停機
對於任何乙個線上應用,如何在服務更新部署過程中保證客戶端無感知是開發者必須要解決的問題,即從應用停止到重啟恢復服務這個階段不能影響正常的業務請求。理想條件下,在沒有請求的時候再進行更新是最安全可靠的,然而網際網路應用必須要保證可用性,因此在技術層面上優化應用更新流程來保證服務在更新時無損是必要的。傳...
Dubbo應用優雅停機實踐
網上相關的帖子很多,主要方法也都是加鉤子hook,這裡我對優雅停機進行了實踐 目前不管是dubbox apache的dubbo alibaba的dubbo都沒有實現真正意義上的優雅停機 截止20191231 標紅是重點,目前jar中自帶的hook並不能滿足先從註冊中心移除 再銷毀容器的順序,且啟用h...