成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Dubbo - Go 優雅上下線設計與實踐

開發 架構
在分布式場景下,微服務進程都是以容器的形式存在,在容器調度系統例如 k8s 的支持下運行,容器組 Pod 是 K8S 的最小資源單位。

一 背景

1 優雅上下線

在分布式場景下,微服務進程都是以容器的形式存在,在容器調度系統例如 k8s 的支持下運行,容器組 Pod 是 K8S 的最小資源單位。隨著服務的迭代和更新,當新版本上線后,需要針對線上正在運行的服務進行替換,從而發布新版本。

在穩定生產的過程中,容器調度完全由 k8s 管控,微服務治理由服務框架或者運維人員進行維護和管理。而在發布新版本,或者擴縮容的場景下,會終止舊的容器實例,并使用新的容器實例進行替換,對于承載高流量的線上生產環境,這個替換過程的銜接一但出現問題,將在短時間內造成大量的錯誤請求,觸發報警甚至影響正常業務。對于體量較大的廠家,發布過程出現問題所造成的損失會是巨大的。

因此,優雅上下線的訴求被提出。這要求服務框架在擁有穩定服務調用能力,傳統服務治理能力的基礎之上,應當提供服務上下線過程中穩定的保障,從而減少運維成本,提高應用穩定性。

2 期望效果

我認為,理想狀態下優雅上下線的效果,是在一個承載大量流量的分布式系統內,所有組件實例都可以隨意地擴容、縮容、滾動更新,在這種情況下需要保證更新過程中穩定的 tps (每秒請求數) 和 rt(請求時延),并且保證不因為上下線造成請求錯誤。再深一步,就是系統的容災能力,在一個或多個節點不可用的情況下,能保證流量的合理調度,從而盡最大能力減少錯誤請求的出現。

  • Dubbo-go 的優雅上下線能力

Dubbo-go 對優雅上下線的探究可以追溯到三年前,早在1.5早期版本,Dubbo-go 就已經擁有優雅下線能力。通過對終止信號量的監聽,實現反注冊、端口釋放等善后工作,摘除流量,保證客戶端請求的正確響應。

在前一段時間,隨著 Dubbo-go 3.0 的正式發版,我在一條 proposal issue (dubbo-go issue 1685) [1] 中提到了一些生產用戶比較看重的問題,作為 3.x 版本的發力方向,并邀請大家談論對這些方向的看法,其中用戶呼聲最高的特性就是無損上下線的能力,再次感謝社區的王曉偉同學的貢獻。

經過不斷完善和生產環境測試,目前 Dubbo-go 已擁有該能力,將在后續版本中正式與大家見面。

二 Dubbo-go 優雅上下線實現思路

優雅上下線可以分為三個角度。服務端的上線,服務端的下線,和客戶端的容災策略。這三個角度,保證了生產實例在正常的發布迭代中,不出現錯誤請求。

1 客戶端負載均衡機制

以 Apache 頂級項目 Dubbo 為典范的微服務架構在這里就不進行贅述,在分布式場景下,即使在 K8S 內,大多數用戶也會使用第三方注冊組件提供的服務發現能力。站在運維成本、穩定性、以及分層解耦等角度,除非一些特殊情況,很少會直接使用原生 Service 進行服務發現和負載均衡,因此這些能力成為了微服務框架的標配能力。

熟悉 Dubbo 的同學一定了解過,Dubbo 支持多種負載均衡算法,通過可擴展機制集成到框架內。Dubbo-go 亦是如此,針對多實例場景下,可以支持多種負載均衡算法, 例如 RR,隨機數,柔性負載均衡等等。

下圖摘自 Dubbo 官網

Dubbo-go 的負載均衡組件

Dubbo-go 服務框架擁有一套接口級擴展機制,可以根據配置,加載同一組件接口的不同的實現。其中就有隨機算法負載均衡策略,它是 Dubbo-go 默認的負載均衡算法。在使用這種算法進行負載均衡的情況下,所有 provider 都會根據一定的權重策略被隨機選擇。所有的provider 實例都有可能成為下游。

這種較為傳統的負載均衡算法會帶來隱患,即不會因為之前調用的結果,影響到后續調用過程中對下游實例的選擇。因此如果有部分下游實例處在上下線階段,造成短暫的服務不可用,所有隨機到該實例的請求均會報錯,在高流量的場景下,會造成巨大損失。

集群重試策略

下圖摘自Dubbo 官網

Dubbo-go 的集群重試策略是從 Dubbo 借鑒過來的,默認使用 Failover(故障轉移) 邏輯,當然也有failback,fallfast 等策略,也是依靠了組件可擴展能力集成進框架內。

無論是上面提到的負載均衡,還是重試邏輯,都是基于“面向切面編程“的思路,構造一個抽象化 invoker 的實現,從而將流量層層向下游傳遞。對于 Failover 策略,會在負載均衡選擇下游實例的基礎上,增加對錯誤請求的重試邏輯。一旦請求報錯,會選擇下一個 invoker 進行嘗試,直到請求成功,或超過最大請求次數為止。

集群重試策略只是增加了嘗試的次數,降低了錯誤率,但本質上還是無狀態的,當下游服務不可用時,會造成災難性的后果。

黑名單機制

黑名單機制是我去年實習,師兄安排做的第一個需求,大致思路很簡單,將請求拋錯的 invoker 對應實例的 ip 地址加入黑名單,后續不再將流量導入該實例,等過一段時間,嘗試請求它,如果成功就從黑名單中刪除。

這個機制實現邏輯非常簡單,但本質上是將無狀態負載均衡算法升級為了有狀態的。對于一個不可用的下游實例,一次請求會快速將該實例拉黑,其他請求就會識別出黑名單內存在該實例,從而避免了其他的流量。

對于這種策略,在黑名單中保留的超時、嘗試從黑名單移除的策略等,這些變量都應當結合具體場景考慮,本質上就是一個有狀態的故障轉移策略。普適性較強。

P2C 柔性負載均衡算法

柔性負載均衡算法是 Dubbo3 生態的一個重要特性,Dubbo-go 社區正在攜手 Dubbo 一同探索和實踐。一些讀者應該在之前 Dubbo-go 3.0 發布的文章中看過相關介紹。簡單來說,是一個有狀態的,不像黑名單那么“一刀切”的,考慮變量更廣泛、更全面的一種負載均衡策略,會在 P2C 算法的基礎之上,考慮各個下游實例的請求時延、機器資源性能等變量,通過一定策略來確定哪個下游實例最合適,而具體策略,將結合具體應用場景,交由感興趣的社區成員來探索,目前是來自字節的牛學蔚(github@justxuewei) 在負責。

上述諸多負載均衡策略,都是站在客戶端的角度,盡最大能力讓請求訪問至在健康的實例上。在無損上下線角度來考慮,對于處于發布階段的不正常工作的實例,可以由客戶端通過合理的算法和策略,例如黑名單機制來過濾掉。

我認為客戶端負載均衡是通用能力,對無損上下線場景的作用只是錦上添花,并不是的核心要素。究其本質,還是要從被“上下線”的服務端實例來考慮,從而解決根本問題。

2 服務端優雅上線邏輯

相較于客戶端,服務端作為服務的提供者、用戶業務邏輯的實體,在我們討論的場景下邏輯較為復雜。在討論服務端之前,我們還是先重溫一下基礎的服務調用模型。

傳統服務調用模型

參考 Dubbo 官網給出的架構圖,完成一次服務調用,一般需要三個組件:注冊中心,服務端,客戶端。

  •  服務端首先需要暴露服務,監聽端口,從而具備接受請求的能力。
  •  服務端將當前服務信息例如ip和端口,注冊在中心化的注冊中心上,例如Nacos。
  •  客戶端訪問注冊中心,獲取要調用的服務ip和端口,完成服務發現。
  • 服務調用,客戶端針對對應 ip 和端口進行請求。

這簡單的四個步驟,就是 Dubbo-go 優雅上下線策略的核心關注點。正常情況下,四個步驟依此執行下來非常順利,邏輯也非常清晰。而放在一個大規模的生產集群內,在服務上下線時就會出現很多值得考量的細節。

我們要明白,上下線過程中的錯誤是怎么產生的?我們只需要關注兩個錯誤,就是:“一個請求被發送給了一個不健康的實例”,以及“正在處理請求的進程被殺死”,上下線過程中幾乎所有的錯誤都是來自于他們。

服務優雅上線邏輯細節

服務上線時,按照上述的步驟,首先要暴露服務,監聽端口。在保證服務提供者可以正常提供服務之后,再將自身信息注冊在注冊中心上,從而會有來自客戶端的流量發送至自己的ip。這個順序一定不能亂,否則將會出現服務沒有準備好,就收到了請求的情況,造成錯誤。

上面所說的只是簡單的情況。在真實場景下,我們所說的一個服務端實例,往往包含一組相互依賴的客戶端和服務端。在 Dubbo 生態的配置中,被稱為 Service (服務)和 Reference(引用) 。

舉一個業務同學非常熟悉的例子,在一個服務函數內,會執行一些業務邏輯,并且針對多個下游服務發起調用,這些下游可能包含數據庫、緩存、或者其他服務提供者,執行完畢后,返回獲得的結果。這對應到 Dubbo 生態的概念中,其實現就是:Service 負責監聽端口和接受請求,接受的請求會向上層轉發至應用業務代碼,而開發者編寫的業務代碼會通過客戶端,也就是 Reference,請求下游對象。當然這里的下游協議有多種,我們只考慮 dubbo 協議棧。

由上面提到這種常見的服務模型,我們可以認為 Service 是 依賴 Reference 的,一個 Service 的所有 Reference 必須都正常工作后,當前 Service 才能正確接受來自上游的服務。這也就推導出了,Service 應該在 Reference 之后加載,當加載完成所有 Reference 后,保證這些客戶端都可用,再加載 Service,暴露能工作的服務,最后再注冊到注冊中心,喊上游來調用。如果反過來,Service 準備好了而 Reference 沒有,則會造成請求錯誤。

因此,服務上線邏輯是 Consumer 加載 -> Provider 加載 -> Registry 服務注冊。

有讀者可能會疑惑,如果 Consumer 依賴當前 實例自己的 Provider 怎么辦,Dubbo 的實現是可以不走網絡直接發起函數調用,Go 這邊也可以按照這種思路來處理,不過實現還待開發。這種情況相對較少,更多的還是上述大家熟悉的情況。

3 服務端優雅下線邏輯

相比于服務上線,服務下線需要考慮的點更多一些。我們重新回到上一節提到的服務調用模型四步驟:

  • 服務端首先需要暴露服務,監聽端口,從而具備接受請求的能力。
  •  服務端將當前服務信息例如ip和端口,注冊在中心化的注冊中心上,例如Nacos。
  • 客戶端訪問注冊中心,獲取要調用的服務ip和端口,完成服務發現。
  • 服務調用,客戶端針對對應 ip 和端口進行請求。

如果一個服務將要下線,則一定要把相關的善后工作做好?,F在的線上情況是這樣:客戶端正在源源不斷地給當前實例請求,如果這個時候直接結束當前進程,一方面,將在一瞬間會有大量的 tcp 建立連接失敗,只能寄希望于第一章提到的客戶端負載均衡策略了;另一方面,有大量正在處理的請求被強制丟棄。這很不優雅!所以當實例知道自己要被終止后,首先要做的就是告訴客戶端:“我這個服務要被終止了,快把流量切走”。這體現在實現中,就是把自身的服務信息從注冊中心刪除。客戶端拿不到當前實例IP后,不會再將請求發過來,這個時候再終止進程才優雅。

上面所說的,也只是簡單的情況。在真實場景之下,客戶端可能并沒有那么快地把流量切走,并且當前服務手里還有一大批正在處理的任務,如果貿然終止進程,可以形象地理解成將端在手里的一盆水撒了一地。

有了這些鋪墊,我們來詳細地聊一聊服務下線的步驟。

優雅下線的使用和觸發

上面的小故事里面提到,進程首先要知道自己“要被終止”了,從而觸發優雅下線邏輯。這個消息可以是信號量,當 k8s 要終止容器進程,會由 kubelet 向進程發送 SIGTERM 信號量。在 Dubbo-go 框架內預置了一系列終止信號量的監聽邏輯,從而在收到終止信號后,依然能由進程自己來控制自己的行動,也就是執行優雅下線邏輯。

不過有些應用會自己監聽 SIGTERM 信號處理下線邏輯。比如,關閉 db 連接、清理緩存等,尤其是充當接入層的網關類型應用,web 容器和 RPC 容器同時存在。這個時候先關閉 web 容器還是先關閉 RPC 容器就顯得尤其最重要。所以 Dubbo-go 允許用戶通過配置internal.signal來控制 signal信號監聽的時機,并通過 graceful_shutdown.BeforeShutdown()在合適的時機優雅關閉 rpc 容器。同樣,Dubbo-go 也允許用戶在配置中選擇是否啟用新號監聽。

反注冊

上面提到,服務端需要告訴客戶端自己要終止了,這個過程就是通過注冊中心進行反注冊(Unregister)。常見的服務注冊中間件,例如 Nacos 、Zookeeper、Polaris 等都會支持服務反注冊,并將刪除動作以事件的形式通知給上游客戶端??蛻舳艘欢ㄊ请S時保持對注冊中心的監聽的,能否成功請求與否,很大程度取決于來自注冊中心的消息有沒有被客戶端及時監聽和作出響應。

在 Dubbo-go 的實現中,客戶端會第一時間拿到刪除事件,將該實例對應 invoker 從緩存中刪除。從而保證后續的請求不會再流向該 invoker 對應的下游。

反注冊過程雖然很快,但畢竟是跨越三個組件之間的事情,無法保證瞬間完成。因此便有了下一步:等待客戶端更新。

和后面步驟有些關聯的是,在當前階段只進行反注冊,而不能進行反訂閱,因為在優雅下線執行的過程中,還會有來自自身客戶端向下游的請求,如果反訂閱,將會無法接收到下游的更新信息,可能導致錯誤。

等待客戶端更新

服務端在優雅下線邏輯的反注冊執行后,不能快速殺死當前服務,而會阻塞當前優雅下線邏輯一小段時間,這段時間由開發人員配置,默認3s,應該大于從反注冊到客戶端刪除緩存的時間。

經過了這段等待更新的時間,服務端就可以認為,客戶端已經沒有新的請求發送過來了,便可以亮起紅燈,邏輯是拒絕一切新的請求。

等待來自上游的請求完成

這里還是不能殺死當前進程,這就像自己的手里還端著那盆水,之前做的只是離開了注水的水龍頭,但并沒有把盆里的水倒干凈。因此要做的還是等待,等待當前實例正在處理的,所有來自上游的請求都完成。

服務端會在一層 filter 維護一個并發安全的計數器,記錄所有進入當前實例但未返回的請求數目。優雅下線邏輯會在這時輪詢計數器,一旦計數器歸零,視為再也沒有來自上游的請求了,手里端著的來自上游的水也就倒干凈了。

等待自己發出的請求得到響應

走到這一步,整條鏈路中,自己上游的請求都移除干凈了。但自己往下游發出的請求還是個未知數,此時此刻也許有大量由當前實例發出,但未得到響應的請求。如果這時貿然終止當前進程,會造成不可預知的問題。

因此還是類似于上述的邏輯,服務在客戶端 filter 維護一個線程安全的計數器,由優雅下線邏輯來輪詢,等待所有請求都已經返回,計數器歸零,方可完成這一階段的等待。

如果當前實例存在一個客戶端,源源不斷地主動向下游發起請求,計數器可能一直不歸零,那就要依靠這一階段的超時配置,來強行結束這一階段了。

銷毀協議,釋放端口

這時,就可以放心大膽地做最后的工作了,銷毀協議、關閉監聽,釋放端口,反訂閱注冊中心。用戶可能希望在下線邏輯徹底結束后,端口釋放后,執行一些自己的邏輯,所以可以提供給開發者一個回調接口。

三 優雅上下線的效果

按照上述的介紹,我們在集群內進行了壓測實驗和模擬上下線實驗。

使用一個 client 實例,5個 proxy 實例,5個 provider 實例,請求鏈路為:

client -> proxy -> provider

因為資源問題,我們選擇讓客戶端保證 5000 tps 的壓力,通過 dubbo-go 的 prometheus 可視化接口暴露出成功率和錯誤請求計數,之后針對鏈路中游的 proxy 實例和鏈路下游的 provider 實例進行滾動發布、擴容、縮容、實例刪除等一系列實驗,模擬生產發布過程。

期間我記錄了很多數據,可以把一個比較明顯的對比展示出來。

不使用優雅上下線邏輯:更新時成功率大幅降低,錯誤數目持續升高,客戶端被迫重啟。

優雅上下線優化后:無錯誤請求,成功率保持在100%

四 Dubbo-go 在服務治理能力的展望

Dubbo-go v3.0 從去年年底正式發版,到現在過了一個多月左右的時間,3.0 發布對我們而言不是大功告成,而是踏上了展望未來的一個新階梯。我們即將發布 3.1 版本,這一版本將擁有優雅上下線能力。

在 3.0 籌備階段,我有想過如果一款服務框架從傳統設計走向未來,需要一步一步走下來,需要有多個必經之路:從最基本的用戶友好性支持、配置重構、易用性、集成測試、文檔建設;到實現傳輸協議(Dubbo3) Triple-go 的跨生態、穩定、高性能、可擴展、生產可用;再到我們 3.0 發版之后的 服務治理能力、運維能力、可視化能力、穩定性,其中就包括了優雅上下線、流量治理、proxyless;再到形成生態,跨生態集成。這樣走,才能一步一個腳印,不斷積累,不斷迭代。

運維能力和服務治理的充實和優化,將作為后續版本的重要 Feature ,我們將會進一步完善流量治理、路由、Proxyless Service Mesh、還有文中提到的柔性負載均衡算法等方面,這些都是今年社區工作的重點。

Dubbo-go 生態,同開發者同在!

[1] https://github.com/apache/dubbo-go/issues/1685


責任編輯:武曉燕 來源: 阿里技術
相關推薦

2021-04-20 10:20:27

Dubbo網絡通信通信協議

2023-07-14 21:34:40

JVM上下線線程

2022-08-22 13:29:42

微服務應用Java

2024-10-14 08:46:50

Controller開發代碼

2022-11-16 09:27:58

flexbox左右布局均分布局

2018-04-09 14:26:06

Go語法實踐

2023-09-21 22:02:22

Go語言高級特性

2023-06-02 18:37:14

Dubbo異步化接口

2023-02-28 08:57:06

Spring上下線緩存

2021-06-04 10:52:51

kubernetes場景容器

2025-01-13 06:00:00

Go語言gRPC

2022-06-22 06:49:39

Hertz開源HTTP 框架

2021-02-05 18:22:51

GoC剖析

2021-07-07 07:44:20

微服務Nacos緩存

2025-04-01 00:06:50

JavaK8sSpring

2023-10-09 18:35:37

得物Redis架構

2023-05-17 00:15:11

TCCXA模式

2024-12-03 12:02:05

2024-02-19 08:12:15

DIKW 模型指標系統數據倉庫

2024-03-14 09:19:49

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线视频亚洲 | 91久久视频| 中文字幕在线视频精品 | 99精品视频在线 | 久久久tv| 中文字幕 在线观看 | 欧美一级视频在线观看 | 国产一区2区 | 久久久成人免费视频 | 一区二区精品电影 | 成人免费视频久久 | 精品视频在线观看 | 久久精品91久久久久久再现 | 国产精品99久久久久久动医院 | 国产91在线 | 亚洲 | 国产成人精品视频在线观看 | 欧美精品成人 | 黄视频国产 | 日韩在线一区二区三区 | 午夜国产一级片 | 成人高清视频在线观看 | 在线看日韩 | 欧美日韩视频在线 | 午夜性视频 | 欧美精品一区在线发布 | 91麻豆精品国产91久久久更新资源速度超快 | 久久久高清| 亚洲精品 在线播放 | 视频一区在线观看 | 97免费视频在线观看 | 久久久久亚洲 | 国产亚洲一区在线 | 精品日韩一区 | 亚洲精品一二区 | 精品久久精品 | 黑色丝袜三级在线播放 | 久久99精品久久久久久琪琪 | 欧美精品一区二区三区四区 | 一级a爱片性色毛片免费 | 国产精品久久久久无码av | 日本人麻豆 |