分布式架構的興起推動了一些新技術的發展。其中鏈路追蹤技術以其在apm領域的優異表現,成為了分布式架構中不可或缺的一部分。在本文中,我們將談談它的一些經典應用場景,以及筆者所在的團隊如何利用鏈路追蹤技術提公升團隊的研發效能。
如圖所示,在微服務體系中,乙個請求往往需要多個服務協作處理。
凡事有利必有弊,這種模式在給我們帶來更好的可擴充套件性的同時,也帶來了一些新的問題。例如,排查問題的困難:任意節點的異常都可能導致上游鏈路的異常,難以追根溯源;系統拓撲複雜難以把控,健壯性存在隱患。
下面,我們將簡單介紹其在apm領域的應用,以及在服務依賴治理和研發效能提公升方面的實踐。
不合理的依賴,可能導致邊緣系統的故障拖垮核心服務,威脅到分布式系統整體的穩定性。通過鏈路追蹤資料的彙總分析,我們可以繪製出系統間的依賴拓撲,為依賴治理提供資料支撐。
我們一般會從下面三個角度來評估服務依賴的合理性:
隨著業務的發展,研發團隊的規模在一定階段也會相應地不斷提公升,但支撐我們研發活動的基礎設施卻沒有辦法線性增長,這其中最重要的就是聯調或測試環境。
業務發展往往導致並行迭代的增多,而這些並行迭代難免會改動到相同的服務,尤其是一些核心基礎服務。如下圖,
這就會導致兩個問題——
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_$。kafka consumer接收到訊息時,執行和上述rpc框架篩選例項時類似的邏輯即可。
定時任務——
定時任務其實最為特殊。前文中我們提到,在請求的統一入口,查詢請求所對應的環境資訊並寫入鏈路。但是定時任務發起的請求並不是使用者觸發的,它來自系統內部,定時排程元件才是請求的「源頭」。所以我們需要在定時任務執行之初,就加入我們的判斷標識邏輯,這要求我們:
在網易智慧型企業中,鏈路追蹤技術的應用,提公升了我們的問題排查效率以及對請求鏈路的把控,也為服務依賴治理提供了必要的資料支撐。同時環境隔離也極大地提公升了交付效率和測試環境的穩定性,從而提高了研發團隊的整體幸福感。
整體來說,我們構建了統一的鏈路追蹤體系,支撐了服務依賴治理及環境隔離技術的實現,但這並不是終點,我們還可以發掘更多的場景,比如saas系統的多租戶資源隔離,或者異常監控預警。世界很大,一起多探索。
go 鏈路追蹤 go micro 鏈路追蹤
本片介紹go micro中使用jaeger作為鏈路追蹤的使用 jaeger相關知識請見官方文件,這裡使用docker啟動gaeger,作為測試使用 啟動jaeger docker run d p 6831 6831 udp p 16686 16686 jaegertracing all in one...
鏈路追蹤 一文讀懂鏈路追蹤
原文 在微服務橫行的時代,服務化思維逐漸成為了程式設計師的基本思維模式,但是,由於絕大部分專案只是一味地增加服務,並沒有對其妥善管理,當介面出現問題時,很難從錯綜複雜的服務呼叫網路中找到問題根源,從而錯失了止損的 時機。而鏈路追蹤的出現正是為了解決這種問題,它可以在複雜的服務呼叫中定位問題,還可以在...
技術分析 搞懂鏈路追蹤
背景介紹 在微服務橫行的時代,服務化思維逐漸成為了程式設計師的基本思維模式,但是,由於絕大部分專案只是一味地增加服務,並沒有對其妥善管理,當介面出現問題時,很難從錯綜複雜的服務呼叫網路中找到問題根源,從而錯失了止損的 時機。而鏈路追蹤的出現正是為了解決這種問題,它可以在複雜的服務呼叫中定位問題,還可...