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

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

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

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

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

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

? 優(yōu)化

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

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

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

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

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

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

? 技術(shù)原理

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

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

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

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

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

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

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

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

? 技術(shù)原理

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

● 3. 精細(xì)化引流

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

?單應(yīng)用引流

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

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

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

2.容災(zāi):當(dāng)應(yīng)用 B 的其中一個(gè)單元因?yàn)榇a配置變更或其它原因?qū)е麻L(zhǎng)時(shí)間不可用時(shí),可將流量都切到其它部署單元。

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

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

?引流壓測(cè)

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

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

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

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

Match: type = transfer

Action: Group = Group_2

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

● 4. 服務(wù)自愈

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

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

簡(jiǎn)單來(lái)說(shuō),我們?cè)?MOSN 內(nèi)部實(shí)現(xiàn)了一個(gè)異常計(jì)數(shù)器,來(lái)統(tǒng)計(jì)篩選并剔除異常的節(jié)點(diǎn),同時(shí)上報(bào)給自愈中心,對(duì)涉及的節(jié)點(diǎn)進(jìn)行進(jìn)一步自愈動(dòng)作。

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

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

ServiceMesh的價(jià)值

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

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

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

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

小結(jié)

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

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

分享到

zhangnn

相關(guān)推薦