springcloud中微服務的優雅停機(已驗證)


 大部分項目部署中,為了方便,可能都直接使用kill -9 服務的pid來停掉服務。

但是由於Eureka采用心跳的機制來上下線服務,會導致服務消費者調用此已經kill的服務提供者然后出錯。

可以采用以下方式來解決:

核心是先調用方法主動通知Eureka注冊中心服務下線,然后再停掉服務。

 

本文會介紹幾種eureka 注冊中心服務下線的方式

 

最不可取的就是直接使用kill命令停掉服務。

默認情況下,如果Eureka Server在90秒沒有收到Eureka客戶的續約,它會將實例從其注冊表中刪除。但這種做法的不好之處在於, 客戶端已經停止了運行,但仍然在注冊中心的列表中。 雖然通過一定的負載均衡策略或使用熔斷器可以讓服務正常進行,但有沒有方法讓注冊中心馬上知道服務已經下線呢?

 

1、直接關閉服務

kill -9 沒有善后

kill -15  有善后 會發送down狀態到eureka server

kill java進程【不建議】

這種方式簡單粗暴,直接造成的影響就是部分模塊調用時出錯,如果有多台服務器的話,一台一台地重啟還是可以的,前提是調用端得有自己的重試策略,比如使用Feign作為客戶端調用接口的話可以配置ribbon的重試策略,而且被調用方得做好冪等策略,防止重試調用時出現重復數據的問題。
 

 

2、向eureka 注冊中心發送delete 請求,只是取消注冊服務, 當發送心跳時還是會注冊到eureka

 

格式為   eureka地址/eureka/apps/服務名稱/實例名稱

請求方式為delete

下面是取消注冊一個服務的例子。

 

 

 下圖是用postman 發送delete請求

  

 

3.通過eureka變更服務狀態的方式實現服務上下線,不會再發送心跳注冊到eureka server

 

 

 

4. 客戶端主動通知注冊中心下線,下線后不會再注冊到eureka了

如果你的eureka客戶端是是一個spring boot應用,可以通過調用以下代碼通知注冊中心下線。

 

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.netflix.discovery.DiscoveryManager;
import com.shm.common.model.RespVO;
import com.shm.common.util.RespUtil;

@RestController
public class OfflineController {


    @RequestMapping(value = "/offline", method = RequestMethod.GET)
    public RespVO<Object> offLine(){
        DiscoveryManager.getInstance().shutdownComponent();
        return RespUtil.success();
    }
    
    
}

 

 

5、設置服務的狀態,可通過狀態變更來實現再eureka的上下線

pom中加入

actuator的包
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

 


以上的方式都能實現服務的下線,但是有的時候只想要下線某個服務,卻不需要發布,等待事情處理完成后上線此服務,則以上方式就做不到了。這時可以通過設置微服務的狀態來完成此功能。項目中整合了actuator的話就非常簡單了,在項目啟動的時候可以看到控制台的輸出:

 


/actuator/service-registry 可以已Get的方式獲取當前服務的狀態,以Post的方式修改當前服務狀態,如將服務設置為Down狀態,這樣其他微服務接收到此狀態后將不調用此服務。將order服務狀態設置為Down:

 

 

看下執行后的效果:

 

等到流量都沒有進來后,需要發布的話直接發布接口,不需要發布可以直接上線當前服務:

這樣一個服務的上線和下線就優雅的完成了,如果項目中沒有使用Actuator框架,可以模仿Actuator框架的實現方式,詳見類:ServiceRegistryEndpoint

 

如果要再上線:

 

 

 

總結
以上幾種方式都可以實現微服的下線,3和5的方式最為優雅,可以主動下線和上線,在沒有新流量進來后可以隨時發布,這樣在也不用等到半夜12點發布了。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM