完整的一個加密開啟流程如圖所示,首先運維人員在管控面選擇需要開啟加密的應(yīng)用,通過 XDS 完成配置下發(fā)。MOSN 在收到配置以后,會基于 SDS 機制獲取到證書和私鑰在內(nèi)存中,證書和私鑰由統(tǒng)一的 Secret 進行管理,應(yīng)用側(cè)不持久化保存。收到證書和私鑰以后,會向注冊中心發(fā)布本機已經(jīng)支持了加密,注冊中心會向所有訂閱的客戶端進行推送,客戶端收到推送以后,與服務(wù)端的通信切換到加密狀態(tài)。

? 加密狀態(tài)熱切換:連接淘汰機制

我們的加密通信是基于 TLS 進行的實現(xiàn),一個連接在建立好并且開始傳輸數(shù)據(jù)以后,連接上的數(shù)據(jù)是 TLS 加密的還是明文的就已經(jīng)固定了,不存在將一個明文通信的連接變成 TLS 加密連接的情況?;?TLS 這個機制,通信從明文切換到加密時,一定是需要新建一個連接,并且成功完成 TLS 握手。

為了做到在連接切換期間業(yè)務(wù)請求不受影響,MOSN 實現(xiàn)了一個連接淘汰機制,用于連接加密狀態(tài)的熱切換。

每一個請求在 MOSN 中經(jīng)過了路由和負載均衡以后,會選擇到一個后端地址,基于這個地址從連接池中選擇對應(yīng)的長連接轉(zhuǎn)發(fā)請求,在引入了加密切換以后,每次選擇到連接以后,都需要判斷當(dāng)前預(yù)期的加密狀態(tài)和連接的加密狀態(tài)是否匹配,如果不匹配,則會創(chuàng)建新的連接進行加密狀態(tài)的切換,并且使用新連接將連接池中的舊連接代替,這樣就可以確保后續(xù)的請求都使用狀態(tài)匹配的連接。對于被替換的舊連接,我們需要進行淘汰,但是這個淘汰不是簡單的斷開連接,因為舊連接上可能還有正在處理的請求,如果直接將連接斷開就會導(dǎo)致請求有損,這是不能接受的。

那么是如何淘汰舊連接的呢?這里就要講到 MOSN 的長連接保持機制了。為了避免因為異常斷網(wǎng)等導(dǎo)致連接“假死”的情況,在連接空閑時,會主動發(fā)起心跳請求,確保連接處于活躍狀態(tài),而如果服務(wù)端一段時間內(nèi)都沒有收到心跳,則會主動將連接斷開。連接淘汰就是利用這個機制,對于準(zhǔn)備淘汰的連接,我們將停止該連接的心跳發(fā)送,當(dāng)連接上的請求處理結(jié)束后,這個連接上就不再會有任何數(shù)據(jù)的傳輸,經(jīng)過一段時間后,服務(wù)端就會主動將這個連接斷開,此時連接斷開是安全的,不會影響任何請求。

? 優(yōu)化

對應(yīng)用無感知開啟加密,除了指開啟過程中不需要重啟、請求無損等,還包括在開啟以后的資源消耗、RT 影響也需要是無感知的。在實際落地應(yīng)用過程中,由于我們都是使用長連接,TLS 握手帶來的建連消耗只占用了很少一部分,在長連接通信過程中的對稱加密消耗經(jīng)過實際測試幾乎可以忽略不計,看上去鏈路加密對性能的指標(biāo)沒有什么問題。

但是在實際大規(guī)模落地以后,我們發(fā)現(xiàn)部分應(yīng)用開啟了加密以后,內(nèi)存占用有顯著的上漲,經(jīng)過排查,定位到屬于GolangTLS 標(biāo)準(zhǔn)庫實現(xiàn)問題( MOSN 是使用 Golang 編寫的),我們自行優(yōu)化以后,也向Golang官方提了PR回饋社區(qū),目前該 PR 已經(jīng)被Golang官方所接受,預(yù)計在go1.16中發(fā)布,具體實現(xiàn)可以見crypto/tls: pool Conn’s outBuf to reduce memory cost of idle connections

● 2. 自適應(yīng)限流

流量管理本身就是 Mesh 架構(gòu)最為核心的功能之一,我們在 MOSN 中實現(xiàn)了多種策略的限流能力,包括單機 QPS 限流、集群限流、熱點限流、接口熔斷、自適應(yīng)限流等,其中自適應(yīng)限流是一大亮點。

限流是每個技術(shù)同學(xué)都不陌生的名詞,同時也是很多不同角色的同學(xué)頭疼的事情。對于業(yè)務(wù)同學(xué)而言逐個接口做容量評估和壓測回歸費時費心,有限的精力只能投入到重點的接口保障上,難免會漏配一些小流量接口的限流;而負責(zé)質(zhì)量和穩(wěn)定性保障的同學(xué)經(jīng)常在故障復(fù)盤時看到各種漏配限流、錯配限流、壓測故障、線程阻塞等造成的各種故障……

我們希望即使在系統(tǒng)漏配錯配限流的情況下,在系統(tǒng)資源嚴(yán)重不足時 MOSN 能夠精準(zhǔn)的找到導(dǎo)致系統(tǒng)資源不足的罪魁禍?zhǔn)?并實時根據(jù)系統(tǒng)水位自動調(diào)節(jié)異常流量。這就是自適應(yīng)限流想要實現(xiàn)的效果。

? 技術(shù)原理

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

類PID控制流量閉環(huán)自適應(yīng)調(diào)節(jié)

樸素的解釋就是,觸發(fā)限流后一邊觀察系統(tǒng)整體水位,一邊秒級按比例調(diào)節(jié)流量的策略,用一張圖來解釋具體的原理:

1.系統(tǒng)資源檢測:秒級檢測系統(tǒng)資源占用情況,如果連續(xù)超過閾值 N 秒則觸發(fā)基線計算,同時開始拒絕壓測流量進入。

2.基線計算:將當(dāng)前所有的接口統(tǒng)計數(shù)據(jù)遍歷一遍,通過一系列算法找出資源消耗大戶,再把這些大戶里明顯上漲的流量找出來,把他們當(dāng)前的資源占用做個快照存入基線數(shù)據(jù)中。

3.基線調(diào)節(jié)器:將上一步驟存入的基線數(shù)據(jù)根據(jù)實際情況進行調(diào)整,根據(jù)系統(tǒng)資源檢測的結(jié)果秒級的調(diào)整基線值,若系統(tǒng)水位超過閾值則按比例下調(diào)基線值,否則按比例恢復(fù)基線值,如此反復(fù)。

4.限流決策:根據(jù)上述步驟生產(chǎn)的基線數(shù)據(jù)決策是否限流。

自適應(yīng)限流已在全站線上應(yīng)用中大規(guī)模啟用,成功防范了多起業(yè)務(wù)故障。為新春紅包壓測和線上業(yè)務(wù)保駕護航。

? 技術(shù)原理

相較于傳統(tǒng)的限流組件,MOSN中的自適應(yīng)限流具備很多優(yōu)勢,MOSN 架構(gòu)天然的流量劫持讓應(yīng)用無需逐個接入 SDK,也無需為特定語言開發(fā)不同版本的限流組件,同時給業(yè)務(wù)同學(xué)降低了配置的難度,也為業(yè)務(wù)實現(xiàn)了兜底保護。在研發(fā)效能和研發(fā)成本上都取得了明顯的收益。

● 3. 精細化引流

隨著業(yè)務(wù)發(fā)展,應(yīng)用面對越來越多的場景和問題,而我們發(fā)現(xiàn)很多應(yīng)用在各自的業(yè)務(wù)場景和解決問題的過程中對流量的調(diào)度能力有了越來越強的訴求。MOSN 的精細化引流正是為滿足這樣的訴求而生,它將應(yīng)用的流量調(diào)度以原子能力的方式透出,然后控制面和各個平臺對這些原子能力進行場景化的編排使用。基于該能力,目前已支撐灰度發(fā)布,容災(zāi),機房建設(shè)和容量壓測等諸多場景。

?單應(yīng)用引流

單應(yīng)用切流是指在單元化的架構(gòu)下,利用 MOSN 對流量的代理和調(diào)度能力,將應(yīng)用粒度的流量從當(dāng)前部署單元引流到另外的部署單元。

如圖應(yīng)用 A 和應(yīng)用 B 是上下游關(guān)系,它們對等部署在單元 1 和單元 2 兩個部署單元。應(yīng)用 B 將自己的地址注冊到注冊中心。應(yīng)用 A 通過注冊中心發(fā)現(xiàn)應(yīng)用 B 的地址,然后發(fā)起 RPC 調(diào)用,調(diào)用收斂在單元內(nèi)。單元 2 內(nèi)應(yīng)用 B 的 MOSN 根據(jù)切流規(guī)則將來自上游的流量轉(zhuǎn)發(fā)到單元 1 的應(yīng)用 B。單應(yīng)用引流的方式可用于多種場景,如:

1.灰度發(fā)布:當(dāng)應(yīng)用 B 需要做新的迭代發(fā)布,可以先將流量都 100% 切到單元 1,然后完成單元 2 集群的發(fā)布,再將單元 1 的流量逐量回切回來,中間有問題隨時回切。

2.容災(zāi):當(dāng)應(yīng)用 B 的其中一個單元因為代碼配置變更或其它原因?qū)е麻L時間不可用時,可將流量都切到其它部署單元。

3.機房新建:可將已有部署單元的應(yīng)用的流量用該方式引流到新機房內(nèi)的部署單元做驗證。而當(dāng)新的部署單元都完整引流后,這個時候如果出現(xiàn)個別應(yīng)用有問題,也不必將整個部署單元的流量回切,利用單應(yīng)用切流將出問題應(yīng)用的流量切回原部署單元即可。

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

?引流壓測

隨著業(yè)務(wù)發(fā)展,應(yīng)用不斷發(fā)布,在多次迭代之后,應(yīng)用的性能水位離之前的基線已經(jīng)走遠多少了呢。如果沒有一個好的性能管理方式,日常機器集群不斷擴容,增加成本。每次大促臨近,大家開始梳理變更,設(shè)計壓測方案,然后反復(fù)壓測發(fā)現(xiàn)性能問題,再迭代發(fā)布解決問題,時間存在風(fēng)險,問題的積累不可控。引流壓測利用 MOSN 的精細化引流能力,將線上集群流量引流到單機進行性能壓測。每天自動回歸,常態(tài)化地繪制出應(yīng)用的性能基線。

?業(yè)務(wù)鏈路隔離

當(dāng)你給別人轉(zhuǎn)賬,這筆流量其實會經(jīng)過一條具有 n 個應(yīng)用的鏈路的處理。微服務(wù)的架構(gòu)帶來了諸多好處,也會帶來如穩(wěn)定性的一些挑戰(zhàn)。如這筆轉(zhuǎn)賬流量所涉及到鏈路中的 n 個應(yīng)用,任意一個應(yīng)用出現(xiàn)了不可用,就會導(dǎo)致這筆支付失敗。是否可以讓這些應(yīng)用都識別出如支付這樣重要的鏈路,為其提供高可用的保證。基于 MOSN 的引流能力我們做到了業(yè)務(wù)鏈路隔離的方案。

如圖有 A,B,C 三個應(yīng)用,A->B->C 的鏈路承擔(dān)了一筆轉(zhuǎn)賬的完整處理,另外還有應(yīng)用 X,Y,Z 等應(yīng)用和用戶會向 A,B 應(yīng)用發(fā)起調(diào)用。A,B,C 應(yīng)用被分為了 GROUP_1 和 GROUP_2 兩個分組,各自分組的機器在向注冊中心注冊自己地址時會將該分組信息帶上,上游在發(fā)起調(diào)用時因此而能區(qū)分出下游不同分組的集群。再根據(jù)流量的標(biāo)識而選擇將流量路由到哪一個集群。所以平臺下發(fā)給 MOSN 的規(guī)則如下:

Match: type = transfer

Action: Group = Group_2

請求頭中含有 transfer 的流量始終路由到 GROUP_2 分組,其它流量都路由到 GROUP_1 分組。這樣就可以將重要流量隔離于其它流量,避免被其它流量導(dǎo)致的限流熔斷等影響。在機器資源,發(fā)布策略,灰度策略上會有更優(yōu)先的考慮。當(dāng)重要分組的集群出現(xiàn)不可用時,還可將流量切換到其它分組集群以容災(zāi)。

● 4. 服務(wù)自愈

傳統(tǒng)的服務(wù)自愈,需要依賴于外部的探針( probe )。這個探針可以是監(jiān)控系統(tǒng),可以是 k8s liveness probe。實現(xiàn)的方式主要是主動的服務(wù)探活,和被動的日志采集分析。這些方式都存在時延與準(zhǔn)確性的問題。主動的探測可能由于網(wǎng)絡(luò)或探測器負載等原因誤判,導(dǎo)致業(yè)務(wù)被誤自愈;被動的日志分析,則需要長鏈路的日志采集分析系統(tǒng),時間以分鐘級計。

回到根源,自愈本質(zhì)是要解決服務(wù)可用性的問題,而 MOSN 承接了所有的服務(wù)流量。因此在 MOSN 內(nèi)部的自愈邏輯可以說是放在了離問題最近的地方。

簡單來說,我們在 MOSN 內(nèi)部實現(xiàn)了一個異常計數(shù)器,來統(tǒng)計篩選并剔除異常的節(jié)點,同時上報給自愈中心,對涉及的節(jié)點進行進一步自愈動作。

首先我們在 MOSN 內(nèi)部對于每個服務(wù)的異常請求做了統(tǒng)計計數(shù)。當(dāng)統(tǒng)計視角可以區(qū)分出有明顯問題的遠端節(jié)點時,可以暫時的將該節(jié)點放入本機的調(diào)用黑名單中,避免問題持續(xù)。依賴于調(diào)用請求的頻率,統(tǒng)計的時間窗口可以從亞分鐘級到秒級。對于高頻的重要服務(wù),單機問題的待續(xù)時間也被限制在了秒級,實現(xiàn)了服務(wù)的秒級自愈。

被黑名單的節(jié)點還需要進一步的處理。當(dāng)節(jié)點被放入黑名單的同時,它的信息也會上報到自愈中心,并開始經(jīng)歷數(shù)分鐘的冷卻時間,等待問題的進一步確認。自愈中心基于上報的黑名單節(jié)點再做二次聚合,并可以結(jié)合被動監(jiān)控和主動探測等方式,在分鐘級的時間內(nèi)使用重啟或下線等手段完成恢復(fù)動作。最終自愈中心確認為沒有問題的節(jié)點,也會在冷卻時間后恢復(fù)服務(wù)。

ServiceMesh的價值

以上只是例舉的幾個能力建設(shè),實際上還有許多能力和落地場景這里就不再一一展開。Service Mesh 在螞蟻落地之后,我們的基礎(chǔ)組件能力得到了飛速的發(fā)展。這得益于 Service Mesh 將業(yè)務(wù)和基礎(chǔ)設(shè)施解耦之后所帶來的紅利。

例如上文中講到的“業(yè)務(wù)鏈路隔離”,其實在很早之前我們有這個方案,可是受制于“上游系統(tǒng)難以推動升級”而一直未落地。在螞蟻的應(yīng)用規(guī)模之下,絕大部分系統(tǒng)的上游數(shù)量都是巨大的,技術(shù)棧是多樣的,基礎(chǔ)組件版本是參差不齊的。

再例如“自適應(yīng)限流”和“服務(wù)自愈”,這兩項技術(shù)存在一定的復(fù)雜性,它在有效性和穩(wěn)定性上都存在一定的挑戰(zhàn)。需要在足夠多的真實場景下不斷去驗證,去試錯和迭代。而在 Mesh 之前的時代,全集群的基礎(chǔ)組件升級一年不過一兩次。一個新能力沒有把握好一次機會也許就得再等一年。

而今天當(dāng)我們擁有 MOSN 之后,它具備在不打擾業(yè)務(wù)的情況下將一個基礎(chǔ)能力快速覆蓋到全集群的能力。這些基礎(chǔ)能力在未有 MOSN 的時候其實也能實現(xiàn),但是在現(xiàn)實中卻因其落地時打擾業(yè)務(wù),推進困難,迭代緩慢,版本碎片化嚴(yán)重等各種原因而無法真正實現(xiàn)。所以 Service Mesh 的價值得以體現(xiàn)。今年應(yīng)用系統(tǒng)因基礎(chǔ)設(shè)施升級而發(fā)布的次數(shù)大大減少,而我們的技術(shù)設(shè)施卻得到了前所未有的演進速度。

小結(jié)

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

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

分享到

zhangnn

相關(guān)推薦