實用技巧:Spring Cloud中,如何優雅下線微服務?

原文:http://www.itmuch.com/spring-cloud-sum/how-to-unregister-service-in-eureka/ ,轉載請說明出處。html

在生產環境中,服務的上下線是不可避免的,咱們但願可以優雅地下線微服務。本文基於Spring Boot 2.x + Spring Cloud Finchley講解實際項目中優雅下線服務的四種方式,並探討各方式的優缺點。java

:Spring Boot 1.x + Spring Cloud Edgware及以前的方式相同,但配置有區別,本文不作討論。web

方式一:kill java進程【不建議】

使用方式:spring

kill java進程ID

該方式藉助的是Spring Boot應用的Shutdown hook,應用自己的下線也是優雅的,但若是你的服務發現組件使用的是Eureka,那麼默認最長會有90秒的延遲,其餘應用纔會感知到該服務下線,這意味着:該實例下線後的90秒內,其餘服務仍然可能調用到這個已下線的實例。所以,該方式是不夠優雅的 。shell

方式二:/shutdown 端點【不建議】

Spring Boot提供了/shutdown 端點,能夠藉助它實現優雅停機。使用方式:json

  • 在想下線應用的applicationyml 中添加以下配置,從而啓用並暴露/shutdown 端點:app

    management:
      endpoint:
        shutdown:
          enabled: true
      endpoints:
        web:
          exposure:
            include: shutdown
  • 發送POST請求到/shutdown 端點負載均衡

    curl -X http://你想中止的服務地址/actuator/shutdown

該方式本質和方式一是同樣的,也是藉助Spring Boot應用的Shutdown hook去實現的。運維

方式三:/pause 端點【生產可用,但有一點缺陷】

Spring Boot應用提供了/pause 端點,利用該端點可實現優雅下線。curl

使用方式:

  • 在想下線應用的application.yml 中添加配置,從而啓用並暴露/pause 端點:

    management:
      endpoint:
        # 啓用pause端點
        pause:
          enabled: true
        # 啓用restart端點,之因此要啓用restart端點,是由於pause端點的啓用依賴restart端點的啓用。詳見:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_endpoints
        restart:
          enabled: true
      endpoints:
        web:
          exposure:
            include: pause,restart
  • 發送POST請求到/actuator/pause 端點:

    curl -X POST http://你想中止的服務實例地址/actuator/pause
  • 執行後的效果相似下圖:

    下線後的效果圖

    如圖所示,該應用在Eureka Server上的狀已被標記爲DOWN可是應用自己其實依然是能夠正常對外服務的。在Spring Cloud中,Ribbon作負載均衡時,只會負載到標記爲UP 的實例上。利用這兩點,你能夠:先用pause端點,將要下線的應用標記爲DOWN,但不去真正中止應用;而後過必定的時間(例如90秒,或者本身作個監控,看當前實例的流量變成0後)再去中止應用,例如kill 應用 ,固然若是你足夠變態,kill -9 也能夠

缺點&侷限

缺點 描述
不一樣的版本配置不大同樣 早期的Spring Cloud版本中,,pause端點是不依賴restart端點的,後來一個pull request致使pause端點必須依賴restart端點…我的給官方提issue,官方最後選擇了繼續依賴,我也是醉了……
沒法和Eureka的健康檢查配合使用 若是你的服務發現組件用的是Eureka,而且你的應用開啓了健康檢查(eureka.client.healthcheck.enabled = true那麼/pause 端點無效!!!

方式四:/service-registry 端點【生產可用】

使用方式:

  • 在想下線應用的application.yml 中添加配置,從而暴露/service-registry 端點:

    management:
      endpoints:
        web:
          exposure:
            include: service-registry

    發送POST請求到/actuator/service-registry 端點:

    curl -X "POST" "http://localhost:8000/actuator/service-registry?status=DOWN" \
       -H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8"

    實行後的效果相似以下圖:

    下線後的效果圖

    由圖可知,使用/service-registry 端點可實現相似/pause 端點的效果。

缺點

暫時沒有發現缺點。

拓展一下

在實際項目中,你能夠作一個運維工具:

  • 運維工具讀取服務發現組件中的全部服務。
  • 有一天你想下線某個服務的時候,就點擊該示例的「優雅下線」 按鈕,該按鈕會請求到想要下線的服務的/pause 端點或者service-registry 端點(看你能不能容忍/pause 端點的缺點),這樣就能夠把該實例在Eureka上標記爲DOWN,流量過一段時間後就不會打到這個實例上。
  • 作一個流量檢測工具(例如QPS統計,這種百度隨便找下,最簡單的一個過濾器 + map就能夠作了),若是檢測到當前實例確實已經沒有流量進入,就在運維工具上點擊另外一個按鈕,例如中止。真正中止應用。
    • 固然,如何中止應用又是另外一個問題了,例如你能夠請求實例的shutdown端點(Spring Boot提供了優雅下線的端點),或者用腳本kill,或者若是是容器能夠藉助一些探針……
相關文章
相關標籤/搜索