SpringCloud升級之路2020.0.x版-3.Eureka Server 與 API 網關要考慮的問題


本系列為之前系列的整理重啟版,隨着項目的發展以及項目中的使用,之前系列里面很多東西發生了變化,並且還有一些東西之前系列並沒有提到,所以重啟這個系列重新整理下,歡迎各位留言交流,謝謝!~

之前我們提到了,不同的集群,使用的是同一套 Eureka 集群。

我們會動態在線發布每個微服務,在 K8s 的環境下,我們一般使用 ReplicaSet 將我們的微服務部署成無狀態的微服務實例(參考:ReplicaSet);在這種情況下,新的微服務實例地址(ip)和原來的地址一般是不一樣的。在這種情況下,我們想實現實例的快速上下線,即快速感知實例狀態。

這需要兩方面的配置,一是 Eureka 客戶端與實例配置,另一個就是這里要討論的 Eureka 服務器的配置。在正常發布的過程中,我們會先啟動一個新的實例,然后優雅關閉一個老實例,然后再啟動一個新的,再關閉一個老的,以此類推,滾動更新。優雅關閉的時候,一般會從注冊中心 Eureka 注銷自己。但是有異常情況的時候,例如 JVM Stop-the-world,或者死鎖等,優雅關閉可能失敗。還有就是這些異常也可能導致心跳無法正常發送到 Eureka。

所以為了實現實例狀態快速被其他實例感知,我們需要啟動Eureka 主動實例過期檢查,同時,建議關閉掉自我保護機制。主要因為:自我保護主要針對集群中網絡出現問題,或者 Eureka 出現問題導致 Stop-the-world 並且無法恢復,或者壓力過大,導致有很多實例無法發送心跳導致很多實例狀態異常,但是實際實例還在正常工作的情況,不要讓這些實例不參與負載均衡。啟用自我保護的情況下,就會停止對於實例的過期。但是,如果出現這種情況,其實也代表很多實例無法讀取注冊中心了。並且還有一種情況就是,Eureka 重啟,雖然不常見,但是對於鏡像中其他的組件更新(例如 JDK 等)我們還是很頻繁的。在我們的集群中, Eureka 集群壓力不大(服務幾百個實例),並且 Eureka 比較穩定,其實只需要考慮 Eureka 網絡出問題的情況。我傾向於從客戶端對於實例緩存機制來解決這個問題,如果返回實例列表為空,則使用上次的實例列表進行負載均衡,這樣既能解決 Eureka 重啟的情況,又能處理一些 Eureka 網絡隔離的情況。

對於 API 網關,我們使用 Spring Cloud Gatway。Spring Cloud Gateway 是基於 WebFlux(底層即 Project Reactor,基於 Netty 實現)的 API 網關。我們在使用的過程中,遇到並解決了以下一些問題:

  • Spring Cloud Gateway 是純異步響應式的代碼實現,API 網關涉及接口 Body 加密:我們需要對發過來的請求進行解密再發往微服務,之后對微服務返回的響應進行加密再返回給客戶端,這就涉及到了 Body 讀取與修改。在 Spring Cloud Gateway 中如何實現 Body 的讀取與修改呢?這塊要好好考慮實現,並且保證不能有內存泄漏。
  • API 網關需要鑒權,但是鑒權一般是單獨有另一個微服務負責,API 網關需要調用這個微服務,如何在異步的環境下調用呢?
  • 發往微服務的每個請求,都是異步響應非阻塞的,所以可以不像微服務調用微服務那樣做線程隔離,限流也可以不使用客戶端限流,而是每個微服務自己限流
  • 發往微服務的每個請求,是需要有重試機制的。
  • 發往微服務的每個請求,也需要做實例和路徑級別的斷路機制

本小節我們繼續針對注冊中心 Eureka 以及 API 網關需要考慮的異常情況,設計問題等做了詳細的說明與分析。接下來我們將開始入手開始開發我們的框架項目。

微信搜索“我的編程喵”關注公眾號,每日一刷,輕松提升技術,斬獲各種offer


免責聲明!

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



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