天天看點

kamon文檔翻譯(五)--考慮線程模型

考慮線程模型

如trace context manipulation 一節中所描述的,我們總是使用

Tracer

伴随對象存儲和接收目前trace的

TracerContext

。反過來,

Tracer

也會結束存儲局部線程變量的TraceContext.。目前為止,這是最簡單和最可預測的方式存儲TraceContext,也是第三方庫互動TraceContext的方式。為了使得=這種方式能夠發揮作用,你需要完全明白你的應用程式線程模型的工作方式。一些情況下,模型很簡單而且是單線程的,但是,當你以基于事件的方式時,就會變得很複雜。

下面我們描述三種常見的線程模型,并提供指導,讓你知道應該如何操作和跨線程使用TraceContext。

傳統模型

kamon文檔翻譯(五)--考慮線程模型

傳統的模型,尤其是使用servlets時,在于将所有與請求有關的代碼都綁定到一個單線程上。上圖中,後面的小箭頭代表了一個線程,上麥呢的方塊代表了線程被阻塞,直到接收到資料庫的響應。如果你使用一個阻塞的用戶端向外部服務發送一個HTTP請求,你的線程也會因為等待外部服務的響應而被阻塞。當所有的都在一個線程上發生時,你就不需要特殊考慮,隻要使用traceing API就可以了。

增強傳統模型

有時候,按順序等待所有請求傳回不是一個選擇,或者為了使延遲達到最小,需要并發的執行其他任務。這是,常用的方式是在傳統的順序流上增加一個分裂點,允許部分代碼并發執行,最後将所有結果彙總。這仍然阻塞了線程,事實上,與傳統模型相比,這阻塞了更多的線程。但是這時應用程式會執行得快一線。我們稱其為增強傳統模型。模型圖如圖所示:

kamon文檔翻譯(五)--考慮線程模型

當你的應用程式在這個模式下工作時,當你還在主線程中時,你可以将

TraceContext

傳送給其他線程。如果需要這麼做,則依賴tracing API 獲得目前的TraceContext,當你還在主線程中時,将其傳遞給支撐線程将要執行的任務。當你完成的時候,清理好所有的支撐線程很重要,因為當你釋放一個線程,它可能會被立即用于另一個trace。

基于事件的模型

當你采用基于事件的模型時,你需要特别謹慎對待

TraceContext

的傳播,因為當你處理一個請求時很可能會同時引發幾個不同線程處理的不同異步事件,直到完成請求。基于事件的模型如下圖:

kamon文檔翻譯(五)--考慮線程模型

從圖中可以看出,一個請求流的處理過程被分為幾個步驟,當有了需要的傳回時在将來的某個時間點結束。請求流的某些部分需要阻塞線程,像JDBC連接配接資料庫,但是大部分的代碼都是在不同的線程中異步執行。

這個模型中另一個重要的是,在不可預見的時間點,不同的線程發生了不同僚件,對與一個trace有關的第一個事件的處理會引發其他事件,并且,僅僅跟這個特定的trace和循環重複有關。這個模型中,線程不那麼重要,你需要關心的是

TraceContext

是如何與你應用程式中的事件關聯的。

現在,基于事件的模型很常見,我們已經為Scala和Akka提供了基于事件的元件,但是,這種情況下,你需要新的工具,tracing API 會幫助你。