摘要: 原創出處
http://www.iocoder.cn/Eureka/instance-registry-cancel/ 「芋道源碼」歡迎轉載,保留摘要,謝謝!
本文主要基於 Eureka 1.8.X 版本
- 1. 概述
- 2. Eureka-Client 發起下線
- 3. Eureka-Server 接收下線
- 藍框部分,爲本文重點。
- 非藍框部分,Eureka-Server 集羣間複製註冊的應用實例信息,不在本文內容範疇。
- 請支持正版。下載盜版,等於主動編寫低級 BUG 。
- 程序猿DD —— 《Spring Cloud微服務實戰》
- 周立 —— 《Spring Cloud與Docker微服務架構實戰》
- 配置
eureka.registration.enabled = true
,應用實例開啓註冊開關。默認爲false
。 - 配置
eureka.shouldUnregisterOnShutdown = true
,應用實例開啓關閉時下線開關。默認爲true
。 - 調用
ApplicationInfoManager#setInstanceStatus(...)
方法,設置應用實例爲關閉( DOWN )。 調用
#unregister()
方法,實現代碼如下:// DiscoveryClient.javavoid unregister() {// It can be null if shouldRegisterWithEureka == falseif(eurekaTransport != null && eurekaTransport.registrationClient != null) {try {logger.info("Unregistering ...");EurekaHttpResponse<Void> httpResponse = eurekaTransport.registrationClient.cancel(instanceInfo.getAppName(), instanceInfo.getId());logger.info(PREFIX + appPathIdentifier + " - deregister status: " + httpResponse.getStatusCode());} catch (Exception e) {logger.error(PREFIX + appPathIdentifier + " - de-registration failed" + e.getMessage(), e);}}}// AbstractJerseyEurekaHttpClient.javapublic EurekaHttpResponse<Void> cancel(String appName, String id) {String urlPath = "apps/" + appName + '/' + id;ClientResponse response = null;try {Builder resourceBuilder = jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();addExtraHeaders(resourceBuilder);response = resourceBuilder.delete(ClientResponse.class);return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();} finally {if (logger.isDebugEnabled()) {logger.debug("Jersey HTTP DELETE {}/{}; statusCode={}", serviceUrl, urlPath, response == null ? "N/A" : response.getStatus());}if (response != null) {response.close();}}}- 調用
AbstractJerseyEurekaHttpClient#cancel(...)
方法,DELETE
請求 Eureka-Server 的apps/${APP_NAME}/${INSTANCE_INFO_ID}
接口,實現應用實例信息的下線。
- 調用
調用
PeerAwareInstanceRegistryImpl#cancel(...)
方法,下線應用實例。實現代碼如下:1:2: public boolean cancel(final String appName, final String id,3: final boolean isReplication) {4: if (super.cancel(appName, id, isReplication)) { // 下線5: // Eureka-Server 複製6: replicateToPeers(Action.Cancel, appName, id, null, null, isReplication);7: // 減少 `numberOfRenewsPerMinThreshold` 、`expectedNumberOfRenewsPerMin`8: synchronized (lock) {9: if (this.expectedNumberOfRenewsPerMin > 0) {10: // Since the client wants to cancel it, reduce the threshold (1 for 30 seconds, 2 for a minute)11: this.expectedNumberOfRenewsPerMin = this.expectedNumberOfRenewsPerMin - 2;12: this.numberOfRenewsPerMinThreshold = (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());13: }14: }15: return true;16: }17: return false;18: }- 第 4 行 :調用父類
AbstractInstanceRegistry#cancel(...)
方法,下線應用實例信息。 - 第 6 行 :Eureka-Server 複製下線操作,在 《Eureka 源碼解析 —— Eureka-Server 集羣同步》 有詳細解析。
- 第 7 至 14 行 :減少
numberOfRenewsPerMinThreshold
、expectedNumberOfRenewsPerMin
,自我保護機制相關,在 《Eureka 源碼解析 —— 應用實例註冊發現(四)之自我保護機制》 有詳細解析。
- 第 4 行 :調用父類
- 第 9 行 :獲取讀鎖。在 《Eureka源碼解析 —— 應用實例註冊發現 (九)之歲月是把萌萌的讀寫鎖》 詳細解析。
- 第 10 至 11 行 :增加下線次數到監控。配合 Netflix Servo 實現監控信息採集。
- 第 12 至 17 行 :移除租約映射(
registry
)。 第 18 至 21 行 :添加到最近下線的調試隊列(
recentCanceledQueue
),用於 Eureka-Server 運維界面的顯示,無實際業務邏輯使用。實現代碼如下:/*** 最近取消註冊的調試隊列* key :添加時的時間戳* value :字符串 = 應用名(應用實例信息編號)*/private final CircularQueue<Pair<Long, String>> recentCanceledQueue;第 22 至 26 行 :移除應用實例覆蓋狀態映射。在《應用實例註冊發現 (八)之覆蓋狀態》詳細解析。
- 第 27 至 31 行 :租約不存在,返回下線失敗(
false
)。 第 34 行 :調用
Lease#cancel()
方法,取消租約。實現代碼如下:// Lease.javapublic void cancel() {if (evictionTimestamp <= 0) {evictionTimestamp = System.currentTimeMillis();}}第 35 至 45 行 :設置應用實例信息的操作類型爲添加,並添加到最近租約變更記錄隊列(
recentlyChangedQueue
)。recentlyChangedQueue
用於註冊信息的增量獲取,在《應用實例註冊發現 (七)之增量獲取》詳細解析。實現代碼如下:/*** 最近租約變更記錄隊列*/private ConcurrentLinkedQueue<RecentlyChangedItem> recentlyChangedQueue = new ConcurrentLinkedQueue<RecentlyChangedItem>();第 47 行 :設置響應緩存( ResponseCache )過期,在《Eureka 源碼解析 —— 應用實例註冊發現 (六)之全量獲取》詳細解析。
- 第 49 行 :返回下線失敗(
false
)。 - 第 53 行 :釋放鎖。
1. 概述
本文主要分享 Eureka-Client 向 Eureka-Server 下線應用實例的過程。
FROM 《深度剖析服務發現組件Netflix Eureka》 二次編輯
推薦 Spring Cloud 書籍:
2. Eureka-Client 發起下線
應用實例關閉時,Eureka-Client 向 Eureka-Server 發起下線應用實例。需要滿足如下條件纔可發起:
實現代碼如下:
|
3. Eureka-Server 接收下線
3.1 接收下線請求
com.netflix.eureka.resources.InstanceResource
,處理單個應用實例信息的請求操作的 Resource ( Controller )。
下線應用實例信息的請求,映射 InstanceResource#cancelLease()
方法,實現代碼如下:
|
3.2 下線應用實例信息
調用 AbstractInstanceRegistry#cancel(...)
方法,下線應用實例信息,實現代碼如下:
|