文 | 丹青算法
網易智慧企業資深架構師架構
鏈路追蹤背景app
如圖所示,在微服務體系中,一個請求每每須要多個服務協做處理。負載均衡
凡事有利必有弊,這種模式在給咱們帶來更好的可擴展性的同時,也帶來了一些新的問題。例如,排查問題的困難:任意節點的異常均可能致使上游鏈路的異常,難以追根溯源;系統拓撲復雜難以把控,健壯性存在隱患。框架
2010年,谷歌發表了一篇論文,介紹了谷歌的內部鏈路追蹤系統Dapper的設計,鏈路追蹤技術自此進入社區的視野。分佈式
下面,咱們將簡單介紹其在APM領域的應用,以及在服務依賴治理和研發效能提高方面的實踐。ide
APM微服務
分佈式系統中,一個請求會在多個節點之間流轉,APM經過TraceID將整條請求處理鏈路中的相關節點關聯起來,並記錄每一個節點的執行時間等信息,造成請求的生命週期鏈路。工具
如圖,咱們能夠很直觀地看到請求通過了哪些節點,以及各個節點的處理耗時。這使得咱們在關注服務自己運行狀態的同時,還能從請求生命週期的視角關注到整條請求鏈路上的全部細節及指標,大幅提升了咱們排查定位問題的效率。測試
服務依賴治理
不合理的依賴,可能致使邊緣系統的故障拖垮核心服務,威脅到分佈式系統總體的穩定性。經過鏈路追蹤數據的彙總分析,咱們能夠繪製出系統間的依賴拓撲,爲依賴治理提供數據支撐。
咱們通常會從下面三個角度來評估服務依賴的合理性:
研發效能提高
隨着業務的發展,研發團隊的規模在必定階段也會相應地不斷提高,但支撐咱們研發活動的基礎設施卻沒有辦法線性增加,這其中最重要的就是聯調或測試環境。
業務發展每每致使並行迭代的增多,而這些並行迭代不免會改動到相同的服務,尤爲是一些核心基礎服務。以下圖,
這就會致使兩個問題——
1. 環境爭奪。如圖,Story-B須要部署ticket服務,與此同時Hotfix-A也等待驗證,一樣須要部署ticket服務,這意味着至少有一方會被阻塞等待,這種串行模式,極大地下降了咱們的交付效率。並行迭代越多,效率下降越明顯。
2. 環境的穩定性。服務之間是相互聯繫的,任何服務的不穩定均可能會致使該環境的不穩定。上圖中的auth服務,幾乎要被全部的業務流程使用。若是Story-A部署auth服務時,重啓/部署的過程不夠平滑,或者Story-A的代碼中存在某些bug,那麼會形成整個測試環境的不穩定。
項目規模不大時,咱們每每能經過一些管理手段來協調。例如版本串行化,經過將迭代計劃錯開,避免在同一個時間段都要去部署某個服務。測試環境只部署特定分支,須要驗證時則將各自的代碼都合併到此分支;要求部署到測試環境的代碼必須達到某種標準以提高測試環境的穩定性。
然而咱們也能夠看到,管理手段的有效性是和團隊規模微服務規模反相關的,咱們須要有技術手段來達到更好的效果。
細想一下,其實問題的根源是你們共用一套測試環境,因此咱們的研發活動出現了資源競爭,咱們對某個服務的操做可能影響到其餘服務。
那麼,可否讓你們都能輕鬆建立各自的環境,且各個環境的使用互不影響呢?
如上圖,Story-A須要部署user和auth服務,那麼咱們建立env-1並部署咱們的user和auth; Story-B須要部署ticket服務,那麼咱們就建立env-2並部署ticket服務;env-3同理。
爲了描述方便,咱們把上圖中的env-x環境,叫測試環境;圖中的下半部分,叫回歸環境。測試環境只包含本次迭代須要部署的應用,迴歸環境包含全部應用。
當咱們使用這套機制時,咱們指望env-1的使用者,請求user和auth服務時只會路由到env-1環境,請求其餘服務時路由到迴歸環境。env-2環境的使用者,請求ticket服務時只會路由到env-2環境,請求其餘服務時一樣路由到迴歸環境。
也就是說,對於環境使用者的請求,若是相關的應用在該環境內,則請求只會被該環境內的應用處理,不然路由到迴歸環境處理。
迴歸環境是一個包含全部服務的相對穩定的環境,開發和提測不容許在迴歸環境部署,以此來保證足夠的穩定性。
研發流程方面,咱們再也不像之前同樣部署到你們都在使用的環境中去驗證,而是各自建立各自獨享的環境,在本身的環境中完成相關工做。
咱們將上述機制稱之爲環境隔離,要實現環境隔離,技術側至少須要實現兩方面的能力:
識別並傳遞請求對應的環境信息
首先,咱們須要能將請求和測試環境關聯起來。
識別請求對應的環境信息,這意味着咱們在建立測試環境時須要指明某種標識,且這種標識咱們能夠從請求中提取出,從而經過雙方標識的匹配來完成關聯,這種標識能夠是用戶帳號、某組IP,或者企業租戶,使用哪一種方式不重要,重要的是結合業務特色達到方便易用的目的。
例如,在咱們的SaaS系統七魚裏,咱們使用租戶id來做爲咱們的標識。在咱們的平臺建立測試環境時,除了指明要部署的應用外,咱們還須要輸入租戶信息,經過這種方式完成請求和測試環境的映射。
咱們能夠在請求的統一入口處(例如,網關),獲取到請求所屬的租戶,以後咱們能夠進一步拿到它所屬的環境信息(環境ID、應用列表)。相似於鏈路跟蹤系統在請求鏈中傳輸TraceID,咱們在請求鏈中附加上環境信息,爲環境隔離打下基礎。
⼲預中間件的實例選擇/消費規則
咱們以微服務架構中最經常使用的幾個組件爲例,談談環境隔離的實現方式。
RPC框架——
RPC的核心流程:provider實例將本身註冊到註冊中心,consumer經過註冊中心獲取provider實例列表,根據必定的實例篩選策略和負載均衡算法,選擇其中一個實例發起調用。
因此改造的手段很明確,provider啓動時,咱們在元數據中寫入環境ID。在實例選擇時,咱們從請求的鏈路數據中拿出環境ID與之作匹配。
須要特別注意的是,匹配不到符合要求的實例時,咱們不能簡單的認爲no provider而讓程序報錯,咱們須要考慮該provider所屬的應用是否在對應環境應用列表中,若是不在,咱們須要將請求路由到迴歸環境中。
消息中間件——
RPC在調用以前有如上所述的實例篩選過程,但消息中間件沒有這個邏輯,不過咱們依然能夠干預消費規則,即在消費者拿到消息後判斷是丟棄消息仍是消費該消息。以kafka爲例,測試環境的kafka consumer啓動時,修改consumer groupid爲groupid_${env}。kafka consumer接收到消息時,執行和上述RPC框架篩選實例時相似的邏輯便可。
定時任務——
定時任務其實最爲特殊。前文中咱們提到,在請求的統一入口,查詢請求所對應的環境信息並寫入鏈路。可是定時任務發起的請求並非用戶觸發的,它來自系統內部,定時調度組件纔是請求的「源頭」。因此咱們須要在定時任務執行之初,就加入咱們的判斷標識邏輯,這要求咱們:
結束語
在網易智慧企業中,鏈路追蹤技術的應用,提高了咱們的問題排查效率以及對請求鏈路的把控,也爲服務依賴治理提供了必要的數據支撐。同時環境隔離也極大地提高了交付效率和測試環境的穩定性,從而提升了研發團隊的總體幸福感。
總體來講,咱們構建了統一的鏈路追蹤體系,支撐了服務依賴治理及環境隔離技術的實現,但這並非終點,咱們還能夠發掘更多的場景,好比SaaS系統的多租戶資源隔離,或者異常監控預警。世界很大,一塊兒多探索。