欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中Eureka的服務(wù)下線詳解

 更新時(shí)間:2023年11月21日 09:42:49   作者:dalianpai  
這篇文章主要介紹了Spring中Eureka的服務(wù)下線詳解,根據(jù)默認(rèn)的策略,如果在一定的時(shí)間內(nèi),客戶端沒有向注冊(cè)中心發(fā)送續(xù)約請(qǐng)求,那么注冊(cè)中心就會(huì)將該實(shí)例從注冊(cè)中心移除,需要的朋友可以參考下

Eureka 下線

// DiscoveryClient.java
   @PreDestroy
    @Override
    public synchronized void shutdown() {
        if (isShutdown.compareAndSet(false, true)) {
            logger.info("Shutting down DiscoveryClient ...");
 
            if (statusChangeListener != null && applicationInfoManager != null) {
                applicationInfoManager.unregisterStatusChangeListener(statusChangeListener.getId());
            }
 
            cancelScheduledTasks();
 
            // If APPINFO was registered
            if (applicationInfoManager != null
                    && clientConfig.shouldRegisterWithEureka()
                    && clientConfig.shouldUnregisterOnShutdown()) {
                //講服務(wù)實(shí)例的狀態(tài)設(shè)置為DOWN
                applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
                //取消注冊(cè)
                unregister();
            }
 
            //關(guān)閉網(wǎng)絡(luò)通信組件
            if (eurekaTransport != null) {
                eurekaTransport.shutdown();
            }
 
            //關(guān)閉監(jiān)聽器
            heartbeatStalenessMonitor.shutdown();
            registryStalenessMonitor.shutdown();
 
            Monitors.unregisterObject(this);
 
            logger.info("Completed shut down of DiscoveryClient");
        }
    }
  • 調(diào)用 ApplicationInfoManager#setInstanceStatus(...) 方法,設(shè)置應(yīng)用實(shí)例為關(guān)閉( DOWN )。
  • 調(diào)用 #unregister() 方法,實(shí)現(xiàn)代碼如下:
// DiscoveryClient.java
void unregister() {
   // It can be null if shouldRegisterWithEureka == false
   if(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.java
@Override
public 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();
        }
    }
}
  • 調(diào)用 AbstractJerseyEurekaHttpClient#cancel(...) 方法,DELETE 請(qǐng)求 Eureka-Server 的 apps/${APP_NAME}/${INSTANCE_INFO_ID} 接口,實(shí)現(xiàn)應(yīng)用實(shí)例信息的下線。

com.netflix.eureka.resources.InstanceResource,處理單個(gè)應(yīng)用實(shí)例信息的請(qǐng)求操作的 Resource ( Controller )。

下線應(yīng)用實(shí)例信息的請(qǐng)求,映射 InstanceResource#cancelLease() 方法,實(shí)現(xiàn)代碼如下:

@DELETE
public Response cancelLease(
       @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
   // 下線
   boolean isSuccess = registry.cancel(app.getName(), id, "true".equals(isReplication));
 
   if (isSuccess) { // 下線成功
       logger.debug("Found (Cancel): " + app.getName() + " - " + id);
       return Response.ok().build();
   } else { // 下線成功
       logger.info("Not Found (Cancel): " + app.getName() + " - " + id);
       return Response.status(Status.NOT_FOUND).build();
   }
}

調(diào)用 AbstractInstanceRegistry#cancel(...) 方法,下線應(yīng)用實(shí)例信息,實(shí)現(xiàn)代碼如下:

@Override
    public boolean cancel(String appName, String id, boolean isReplication) {
        return internalCancel(appName, id, isReplication);
    }
 
    /**
     * {@link #cancel(String, String, boolean)} method is overridden by {@link PeerAwareInstanceRegistry}, so each
     * cancel request is replicated to the peers. This is however not desired for expires which would be counted
     * in the remote peers as valid cancellations, so self preservation mode would not kick-in.
     */
    protected boolean internalCancel(String appName, String id, boolean isReplication) {
        read.lock();
        try {
            CANCEL.increment(isReplication);
            Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
            Lease<InstanceInfo> leaseToCancel = null;
            if (gMap != null) {
                leaseToCancel = gMap.remove(id);
            }
 
            //將服務(wù)實(shí)例加入最近下線的queue中
            recentCanceledQueue.add(new Pair<Long, String>(System.currentTimeMillis(), appName + "(" + id + ")"));
            InstanceStatus instanceStatus = overriddenInstanceStatusMap.remove(id);
            if (instanceStatus != null) {
                logger.debug("Removed instance id {} from the overridden map which has value {}", id, instanceStatus.name());
            }
            if (leaseToCancel == null) {
                CANCEL_NOT_FOUND.increment(isReplication);
                logger.warn("DS: Registry: cancel failed because Lease is not registered for: {}/{}", appName, id);
                return false;
            } else {
                //調(diào)用cancel,保存一個(gè)時(shí)間戳
                leaseToCancel.cancel();
 
                InstanceInfo instanceInfo = leaseToCancel.getHolder();
                String vip = null;
                String svip = null;
                if (instanceInfo != null) {
                    instanceInfo.setActionType(ActionType.DELETED);
                    //丟到最近改變的隊(duì)列中
                    recentlyChangedQueue.add(new RecentlyChangedItem(leaseToCancel));
                    //設(shè)置了最近一次變更的時(shí)間戳
                    instanceInfo.setLastUpdatedTimestamp();
                    vip = instanceInfo.getVIPAddress();
                    svip = instanceInfo.getSecureVipAddress();
 
                    //服務(wù)的注冊(cè),下線,過期,都會(huì)代表這個(gè)服務(wù)實(shí)例變化了,都會(huì)將自己放入最近改變的隊(duì)列中
                    //這個(gè)最近改變的隊(duì)列,只會(huì)保留最近3分鐘的實(shí)例
                    //所以說eureka client拉取增量注冊(cè)表的時(shí)候,其實(shí)就是拉取最近3分鐘有變化的服務(wù)實(shí)例。
                }
                invalidateCache(appName, vip, svip);
                logger.info("Cancelled instance {}/{} (replication={})", appName, id, isReplication);
            }
        } finally {
            read.unlock();
        }
 
        synchronized (lock) {
            if (this.expectedNumberOfClientsSendingRenews > 0) {
                // Since the client wants to cancel it, reduce the number of clients to send renews.
                //修改期望值
                this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews - 1;
                updateRenewsPerMinThreshold();
            }
        }
 
        return true;
    }

到此這篇關(guān)于Spring中Eureka的服務(wù)下線詳解的文章就介紹到這了,更多相關(guān)Eureka的服務(wù)下線內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • AQS加鎖機(jī)制Synchronized相似點(diǎn)詳解

    AQS加鎖機(jī)制Synchronized相似點(diǎn)詳解

    這篇文章主要為大家介紹了AQS加鎖機(jī)制Synchronized相似點(diǎn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 詳解MyBatis resultType與resultMap中的幾種返回類型

    詳解MyBatis resultType與resultMap中的幾種返回類型

    本文主要介紹了MyBatis resultType與resultMap中的幾種返回類型,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 一文帶你搞懂Java中的泛型和通配符

    一文帶你搞懂Java中的泛型和通配符

    泛型機(jī)制在項(xiàng)目中一直都在使用,甚至很多源碼中都用到了泛型機(jī)制。但是里面很多的機(jī)制和特性一直沒有明白,尤其通配符這塊,經(jīng)常忘記。本文對(duì)此做了一些總結(jié),具有一定借鑒價(jià)值,希望有所幫助
    2022-09-09
  • java多線程的同步方法實(shí)例代碼

    java多線程的同步方法實(shí)例代碼

    這篇文章主要介紹了 java多線程的同步方法實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Springboot?接口需要接收參數(shù)類型是數(shù)組問題

    Springboot?接口需要接收參數(shù)類型是數(shù)組問題

    這篇文章主要介紹了Springboot?接口需要接收參數(shù)類型是數(shù)組問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文)

    Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文)

    這篇文章主要介紹了Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Java?多線程并發(fā)ReentrantLock

    Java?多線程并發(fā)ReentrantLock

    這篇文章主要介紹了Java?多線程并發(fā)ReentrantLock,Java?提供了?ReentrantLock?可重入鎖來提供更豐富的能力和靈活性,感興趣的小伙伴可以參考一下
    2022-06-06
  • SpringBoot從Nacos讀取MySQL數(shù)據(jù)庫(kù)配置錯(cuò)誤:Public Key Retrieval is not allowed的解決方案

    SpringBoot從Nacos讀取MySQL數(shù)據(jù)庫(kù)配置錯(cuò)誤:Public Key Retrieva

    最近的項(xiàng)目,突然都從MySQL5.7升級(jí)到8.0了,有些項(xiàng)目能運(yùn)行成功,有些項(xiàng)目遇到了問題,啟動(dòng)不成功,顯示數(shù)據(jù)庫(kù)方面的異常信息,本文給大家介紹了SpringBoot從Nacos讀取MySQL數(shù)據(jù)庫(kù)配置錯(cuò)誤:Public Key Retrieval is not allowed的解決方案,需要的朋友可以參考下
    2024-04-04
  • java新人基礎(chǔ)入門之遞歸調(diào)用

    java新人基礎(chǔ)入門之遞歸調(diào)用

    這篇文章主要給大家介紹了關(guān)于java新人基礎(chǔ)入門之遞歸調(diào)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)

    java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)

    這篇文章主要為大家介紹了java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06

最新評(píng)論