天天看點

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

作者:李唯

來源: 金融級分布式架構公衆号

1. 引言

2019 年 Service Mesh 在螞蟻大規模落地并完美支撐雙十一核心鍊路,對于落地過程在去年已經有系列文章解讀。而在此之後的一年多時間,Service Mesh 在螞蟻又在如何演進呢。本文介紹螞蟻 Service Mesh 在雙十一落地之後所做的探索和思考。

2. 能力建設

得益于 Service Mesh 将業務和基礎設施解耦,在過去一年中我們的基礎設施能力得到了飛快的發展。大量能力大規模落地螞蟻,例如鍊路加密、可信身份認證、服務鑒權、自适應限流、叢集限流、精細化引流、服務自愈等。這裡先對四個能力進行解讀,其它能力後續再有文章講述。

  • 鍊路加密

為了達到一個更高的安全水位,我們預期在螞蟻内部所有的通信 100% 加密覆寫,這就是鍊路加密。

  • 設計

鍊路加密落地最大的挑戰就是加密對業務不能造成影響,包括幾個問題:

  • 必須簡化大規模場景下的運維複雜度問題,需要具備可灰階、可復原的能力。
  • 灰階運作期間,明文和加密切換不能對業務請求造成影響,需要進行熱切換。
  • 開啟加密以後,對性能的影響必須控制在可接受的範圍内。

基于這些需求,完成了鍊路加密的架構設計,主要思路包括:

  • 通過統一的管控面控制服務端應用的配置,基于動态服務釋出與訂閱機制,在服務端支援加密能力以後,用戶端自動進行加密的切換,運維人員隻需要控制服務端配置節奏完成灰階;在灰階運作期間,服務端同一個端口需要同時支援明文和加密的能力。
  • 相比于明文通信,基于 TLS 加密的通信主要消耗在連接配接建立的握手期間,服務端和用戶端采用長連接配接的方式,減少連接配接的建立,以減少開啟加密對性能的影響。
  • 用戶端在感覺到服務端明文和加密狀态變化以後,需要在不同的長連接配接之間進行穩定的切換,後文會詳細介紹。
Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

完整的一個加密開啟流程如圖所示,首先運維人員在管控面選擇需要開啟加密的應用,通過 XDS 完成配置下發。MOSN 在收到配置以後,會基于 SDS 機制擷取到證書和私鑰在記憶體中,證書和私鑰由統一的 Secret 進行管理,應用側不持久化儲存。收到證書和私鑰以後,會向注冊中心釋出本機已經支援了加密,注冊中心會向所有訂閱的用戶端進行推送,用戶端收到推送以後,與服務端的通信切換到加密狀态。

  • 加密狀态熱切換:連接配接淘汰機制

我們的加密通信是基于 TLS 進行的實作,一個連接配接在建立好并且開始傳輸資料以後,連接配接上的資料是 TLS 加密的還是明文的就已經固定了,不存在将一個明文通信的連接配接變成 TLS 加密連接配接的情況。基于 TLS 這個機制,通信從明文切換到加密時,一定是需要建立一個連接配接,并且成功完成 TLS 握手。

為了做到在連接配接切換期間業務請求不受影響,MOSN 實作了一個連接配接淘汰機制,用于連接配接加密狀态的熱切換。

每一個請求在 MOSN 中經過了路由和負載均衡以後,會選擇到一個後端位址,基于這個位址從連接配接池中選擇對應的長連接配接轉發請求,在引入了加密切換以後,每次選擇到連接配接以後,都需要判斷目前預期的加密狀态和連接配接的加密狀态是否比對,如果不比對,則會建立新的連接配接進行加密狀态的切換,并且使用新連接配接将連接配接池中的舊連接配接代替,這樣就可以確定後續的請求都使用狀态比對的連接配接。對于被替換的舊連接配接,我們需要進行淘汰,但是這個淘汰不是簡單的斷開連接配接,因為舊連接配接上可能還有正在處理的請求,如果直接将連接配接斷開就會導緻請求有損,這是不能接受的。

那麼是如何淘汰舊連接配接的呢?這裡就要講到 MOSN 的長連接配接保持機制了。為了避免因為異常斷網等導緻連接配接“假死”的情況,在連接配接空閑時,會主動發起心跳請求,確定連接配接處于活躍狀态,而如果服務端一段時間内都沒有收到心跳,則會主動将連接配接斷開。連接配接淘汰就是利用這個機制,對于準備淘汰的連接配接,我們将停止該連接配接的心跳發送,當連接配接上的請求處理結束後,這個連接配接上就不再會有任何資料的傳輸,經過一段時間後,服務端就會主動将這個連接配接斷開,此時連接配接斷開是安全的,不會影響任何請求。

  • 優化

對應用無感覺開啟加密,除了指開啟過程中不需要重新開機、請求無損等,還包括在開啟以後的資源消耗、RT 影響也需要是無感覺的。在實際落地應用過程中,由于我們都是使用長連接配接,TLS 握手帶來的建連消耗隻占用了很少一部分,在長連接配接通信過程中的對稱加密消耗經過實際測試幾乎可以忽略不計,看上去鍊路加密對性能的名額沒有什麼問題。

但是在實際大規模落地以後,我們發現部分應用開啟了加密以後,記憶體占用有顯著的上漲,經過排查,定位到屬于 GolangTLS 标準庫實作問題( MOSN 是使用 Golang 編寫的),我們自行優化以後,也向 Golang 官方提了 PR 回饋社群,目前該 PR 已經被 Golang 官方所接受,預計在 go1.16 中釋出,具體實作可以見 crypto/tls: pool Conn's outBuf to reduce memory cost of idle connections

  • 自适應限流

流量管理本身就是 Mesh 架構最為核心的功能之一,我們在 MOSN 中實作了多種政策的限流能力,包括單機 QPS 限流、叢集限流、熱點限流、接口熔斷、自适應限流等,其中自适應限流是一大亮點。

限流是每個技術同學都不陌生的名詞,同時也是很多不同角色的同學頭疼的事情。對于業務同學而言逐個接口做容量評估和壓測回歸費時費心,有限的精力隻能投入到重點的接口保障上,難免會漏配一些小流量接口的限流;而負責品質和穩定性保障的同學經常在故障複盤時看到各種漏配限流、錯配限流、壓測故障、線程阻塞等造成的各種故障......

我們希望即使在系統漏配錯配限流的情況下,在系統資源嚴重不足時 MOSN 能夠精準的找到導緻系統資源不足的罪魁禍首,并實時根據系統水位自動調節異常流量。這就是自适應限流想要實作的效果。

  • 技術原理
Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

能用一句話說清楚你們的技術原理嗎?

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

類 PID 控制流量閉環自适應調節

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

樸素的解釋就是,觸發限流後一邊觀察系統整體水位,一邊秒級按比例調節流量的政策,用一張圖來解釋具體的原理:

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結
  • 系統資源檢測:秒級檢測系統資源占用情況,如果連續超過門檻值 N 秒則觸發基線計算,同時開始拒絕壓測流量進入。
  • 基線計算:将目前所有的接口統計資料周遊一遍,通過一系列算法找出資源消耗大戶,再把這些大戶裡明顯上漲的流量找出來,把他們目前的資源占用做個快照存入基線資料中。
  • 基線調節器:将上一步驟存入的基線資料根據實際情況進行調整,根據系統資源檢測的結果秒級的調整基線值,若系統水位超過門檻值則按比例下調基線值,否則按比例恢複基線值,如此反複。
  • 限流決策:根據上述步驟生産的基線資料決策是否限流。

自适應限流已在全站線上應用中大規模啟用,成功防範了多起業務故障。為新春紅包壓測和線上業務保駕護航。

相較于傳統的限流元件,MOSN 中的自适應限流具備很多優勢,MOSN 架構天然的流量劫持讓應用無需逐個接入 SDK,也無需為特定語言開發不同版本的限流元件,同時給業務同學降低了配置的難度,也為業務實作了兜底保護。在研發效能和研發成本上都取得了明顯的收益。

MOSN 自适應限流 傳統 QPS 限流元件
規則數量 每個應用隻需要配一個 每個接口都需要配置一個
觸發條件 按系統整體水位 按接口調用量
限流值 動态實時計算 固定值
生效點 在 MOSN 中攔截 在應用的限流元件攔截
接入與更新成本1 已 Mesh 化的應用自帶,無成本 應用接入 SDK ,接入和更新需做釋出
  • 精細化引流

随着業務發展,應用面對越來越多的場景和問題,而我們發現很多應用在各自的業務場景和解決問題的過程中對流量的排程能力有了越來越強的訴求。MOSN 的精細化引流正是為滿足這樣的訴求而生,它将應用的流量排程以原子能力的方式透出,然後控制面和各個平台對這些原子能力進行場景化的編排使用。基于該能力,目前已支撐灰階釋出,容災,機房建設和容量壓測等諸多場景。

  • 單應用引流

單應用切流是指在單元化的架構下,利用 MOSN 對流量的代理和排程能力,将應用粒度的流量從目前部署單元引流到另外的部署單元。

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

如圖應用 A 和應用 B 是上下遊關系,它們對等部署在單元 1 和單元 2 兩個部署單元。應用 B 将自己的位址注冊到注冊中心。應用 A 通過注冊中心發現應用 B 的位址,然後發起 RPC 調用,調用收斂在單元内。單元 2 内應用 B 的 MOSN 根據切流規則将來自上遊的流量轉發到單元 1 的應用 B。單應用引流的方式可用于多種場景,如:

  • 灰階釋出:當應用 B 需要做新的疊代釋出,可以先将流量都 100% 切到單元 1,然後完成單元 2 叢集的釋出,再将單元 1 的流量逐量回切回來,中間有問題随時回切。
  • 容災:當應用 B 的其中一個單元因為代碼配置變更或其它原因導緻長時間不可用時,可将流量都切到其它部署單元。
  • 機房建立:可将已有部署單元的應用的流量用該方式引流到新機房内的部署單元做驗證。而當新的部署單元都完整引流後,這個時候如果出現個别應用有問題,也不必将整個部署單元的流量回切,利用單應用切流将出問題應用的流量切回原部署單元即可。

另外 MOSN 的單應用切流還支援接口級别的切流,支援部署單元之間的多到一,一到多,多到多的方式。這樣靈活的切流方式,為業務帶來了很大的想象空間,相信未來會有越來越多有價值的解決案例在此基礎上生長出來。

  • 引流壓測

随着業務發展,應用不斷釋出,在多次疊代之後,應用的性能水位離之前的基線已經走遠多少了呢。如果沒有一個好的性能管理方式,日常機器叢集不斷擴容,增加成本。每次大促臨近,大家開始梳理變更,設計壓測方案,然後反複壓測發現性能問題,再疊代釋出解決問題,時間存在風險,問題的積累不可控。引流壓測利用 MOSN 的精細化引流能力,将線上叢集流量引流到單機進行性能壓測。每天自動回歸,常态化地繪制出應用的性能基線。

  • 業務鍊路隔離

當你給别人轉賬,這筆流量其實會經過一條具有 n 個應用的鍊路的處理。微服務的架構帶來了諸多好處,也會帶來如穩定性的一些挑戰。如這筆轉賬流量所涉及到鍊路中的 n 個應用,任意一個應用出現了不可用,就會導緻這筆支付失敗。是否可以讓這些應用都識别出如支付這樣重要的鍊路,為其提供高可用的保證。基于 MOSN 的引流能力我們做到了業務鍊路隔離的方案。

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

如圖有 A,B,C 三個應用,A->B->C 的鍊路承擔了一筆轉賬的完整處理,另外還有應用 X,Y,Z 等應用和使用者會向 A,B 應用發起調用。A,B,C 應用被分為了 GROUP_1 和 GROUP_2 兩個分組,各自分組的機器在向注冊中心注冊自己位址時會将該分組資訊帶上,上遊在發起調用時是以而能區分出下遊不同分組的叢集。再根據流量的辨別而選擇将流量路由到哪一個叢集。是以平台下發給 MOSN 的規則如下:

Match: type = transfer

Action: Group = Group_2

請求頭中含有 transfer 的流量始終路由到 GROUP_2 分組,其它流量都路由到 GROUP_1 分組。這樣就可以将重要流量隔離于其它流量,避免被其它流量導緻的限流熔斷等影響。在機器資源,釋出政策,灰階政策上會有更優先的考慮。當重要分組的叢集出現不可用時,還可将流量切換到其它分組叢集以容災。

  • 服務自愈

傳統的服務自愈,需要依賴于外部的探針( probe )。這個探針可以是監控系統,可以是 k8s liveness probe。實作的方式主要是主動的服務探活,和被動的日志采集分析。這些方式都存在時延與準确性的問題。主動的探測可能由于網絡或探測器負載等原因誤判,導緻業務被誤自愈;被動的日志分析,則需要長鍊路的日志采集分析系統,時間以分鐘級計。

回到根源,自愈本質是要解決服務可用性的問題,而 MOSN 承接了所有的服務流量。是以在 MOSN 内部的自愈邏輯可以說是放在了離問題最近的地方。

簡單來說,我們在 MOSN 内部實作了一個異常計數器,來統計篩選并剔除異常的節點,同時上報給自愈中心,對涉及的節點進行進一步自愈動作。

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

首先我們在 MOSN 内部對于每個服務的異常請求做了統計計數。當統計視角可以區分出有明顯問題的遠端節點時,可以暫時的将該節點放入本機的調用黑名單中,避免問題持續。依賴于調用請求的頻率,統計的時間視窗可以從亞分鐘級到秒級。對于高頻的重要服務,單機問題的待續時間也被限制在了秒級,實作了服務的秒級自愈。

被黑名單的節點還需要進一步的處理。當節點被放入黑名單的同時,它的資訊也會上報到自愈中心,并開始經曆數分鐘的冷卻時間,等待問題的進一步确認。自愈中心基于上報的黑名單節點再做二次聚合,并可以結合被動監控和主動探測等方式,在分鐘級的時間内使用重新開機或下線等手段完成恢複動作。最終自愈中心确認為沒有問題的節點,也會在冷卻時間後恢複服務。

3. Service Mesh 的價值

以上隻是例舉的幾個能力建設,實際上還有許多能力和落地場景這裡就不再一一展開。Service Mesh 在螞蟻落地之後,我們的基礎元件能力得到了飛速的發展。這得益于 Service Mesh 将業務和基礎設施解耦之後所帶來的紅利。

例如上文中講到的“業務鍊路隔離”,其實在很早之前我們有這個方案,可是受制于“上遊系統難以推動更新”而一直未落地。在螞蟻的應用規模之下,絕大部分系統的上遊數量都是巨大的,技術棧是多樣的,基礎元件版本是參差不齊的。

再例如“自适應限流”和“服務自愈”,這兩項技術存在一定的複雜性,它在有效性和穩定性上都存在一定的挑戰。需要在足夠多的真實場景下不斷去驗證,去試錯和疊代。而在 Mesh 之前的時代,全叢集的基礎元件更新一年不過一兩次。一個新能力沒有把握好一次機會也許就得再等一年。

而今天當我們擁有 MOSN 之後,它具備在不打擾業務的情況下将一個基礎能力快速覆寫到全叢集的能力。這些基礎能力在未有 MOSN 的時候其實也能實作,但是在現實中卻因其落地時打擾業務,推進困難,疊代緩慢,版本碎片化嚴重等各種原因而無法真正實作。是以 Service Mesh 的價值得以展現。今年應用系統因基礎設施更新而釋出的次數大大減少,而我們的技術設施卻得到了前所未有的演進速度。

4. 小結

在過去的一年多時間裡,螞蟻在 Service Mesh 上建設了大量能力,這些能力在性能,效能,安全,穩定性和可用率等多個方面為業務帶來了幫助,也為基礎設施帶來了快速的演進。而這些最終正是得益于 Service Mesh 将業務和基礎設施的解耦。

在 Service Mesh 落地之後,我們曾設想過 Service Mesh 再向前探索可能會遇到的種種困難,包括資源使用率,性能損耗等等,但是未曾想到其中最先到來也是過去一年中最大的挑戰竟然是它。這裡先留個懸念,待下期文章進行分享。

Service Mesh 雙十一後的探索和思考(上)1. 引言2. 能力建設3. Service Mesh 的價值4. 小結

繼續閱讀