[譯] OpenTracing語義規範

OpenTracing語義規範(中文版)

版本 1.0html

原文

The OpenTracing Semantic Specificationgit

概述

這是一份」正式」的OpenTracing語義規範文檔。因爲OpenTracing是跨語言的,本文檔會盡可能避免提到特定語言相關的概念。也就是說,咱們認爲全部語言都具備相似」接口」這樣的概念,並提供相關的功能。github

版本控制策略

OpenTracing採用了 主版本號.次版本號 形式的版本號,可是沒有 .修訂號 。當對規範進行向後不兼容的更改時,主版本增長。次版本的增長則用於用於不間斷更改,如引入新的標準標記,日誌字段或SpanContext引用類型。(你能夠在這個Issue specification#2 中讀到更多有關此版本控制方案的信息)編程

OpenTracing數據模型

OpenTracing中的Traces由其Span隱式定義。Trace可被認爲是由一組Span定義的有向無環圖(DAG),在Span之間的被稱爲References網絡

如下是一個由8個Span構成的Trace的例子:併發

一個Trace中Span間的因果關係


        [Span A]  ←←←(the root span)
            |
     +------+------+
     |             |
 [Span B]      [Span C] ←←←(Span C之於Span A的關係是 `ChildOf` )
     |             |
 [Span D]      +---+-------+
               |           |
           [Span E]    [Span F] >>> [Span G] >>> [Span H]
                                       ↑
                                       ↑
                                       ↑
                         (Span G `FollowsFrom` Span F)

有時用時間軸來顯示Traces更容易,以下圖所示:編程語言

一個Trace中Span間的時間關係


––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time

 [Span A···················································]
   [Span B··············································]
      [Span D··········································]
    [Span C········································]
         [Span E·······]        [Span F··] [Span G··] [Span H··]

每一個Span封裝了以下狀態:分佈式

  • 操做名稱函數

  • 開始時間戳工具

  • 結束時間戳

  • 一組零或多個鍵:值結構的Span標籤(Tags)。鍵必須是字符串。值能夠是字符串,布爾或數值類型.

  • 一組零或多個Span日誌(Logs),其中每一個都是一個鍵:值映射並與一個時間戳配對。鍵必須是字符串,值能夠是任何類型。 並不是全部的OpenTracing實現都必須支持每種值類型。

  • 一個SpanContext(見下文)

  • 零或多個因果相關的Span間的References (經過那些相關的SpanSpanContext)

每一個SpanContext封裝了以下狀態:

  • 任何須要跟跨進程Span關聯的,依賴於OpenTracing實現的狀態(例如Trace和Span的id)

  • 鍵:值結構的跨進程的Baggage Items

Span間的Reference

一個Span可引用零或多個因果相關的SpanContext。OpenTracing目前定義了兩種類型的Reference: ChildOfFollowsFrom這兩種Reference類型都對父子Span間的因果關係進行了建模。將來,OpenTracing可能會爲不具因果關係的Span提供不一樣類型的Reference (例如批量的Span,卡在隊列中的Span等)。

ChildOf reference: 一個Span能夠是另外一個Span的子Span。在 ChildOf 引用中,父Span在某種程度上取決於子Span。下列狀況會構成 ChildOf 關係:

  • 在一個RPC中,表明服務端的Span可做爲 ChildOf 表明客戶端的Span

  • 在一個持久化進程中,表明SQL插入的Span可做爲 ChildOf 表明ORM save方法的Span

  • 多個併發(多是分佈式)執行任務的Span可能分別各自爲 Childof 一個合併了多個子Span結果的父Span

下列這些都是有效的具備 ChildOf 關係的時序圖

[-Parent Span---------]
         [-Child Span----]

    [-Parent Span--------------]
         [-Child Span A----]
          [-Child Span B----]
        [-Child Span C----]
         [-Child Span D---------------]
         [-Child Span E----]

FollowsFrom reference: 有些父Span不依賴於任何子Span的結果。這種狀況下,咱們僅認爲子Span在因果上 FollowsFrom 父Span。有許多不一樣的 FollowsFrom 引用子類別,在OpenTracing的將來版本中,它們可能會被更正式地區分。

下列這些都是有效的具備 FollowsFrom 關係的時序圖

[-Parent Span-]  [-Child Span-]


    [-Parent Span--]
     [-Child Span-]


    [-Parent Span-]
                [-Child Span-]

OpenTracing接口定義

OpenTracing規範中有三種相互關聯的關鍵類型 TracerSpan ,and SpanContext。接下來,咱們來看一下各類類型的行爲; 簡單來講,每種行爲分別在編程語言中對應爲一個」方法」,儘管實際上多是一組重載方法。

當咱們討論「可選」參數時,應當清楚,不一樣的語言有不一樣的方式來解釋這個概念。好比說,在Go語言中咱們會使用」functional Options」這個術語,而在Java中咱們會使用builder模式。

Tracer

Tracer 接口創造 Span 而且可以跨進程地 Inject (序列化)和 Extract (反序列化)。嚴格來講,它應具備如下能力:

啓動一個新的 Span

必須參數

  • 操做名稱,一我的工可讀的字符串,它簡潔地表示由Span完成的工做 (例如,RPC方法名稱、函數名稱或一個較大的計算任務中的階段的名稱)。操做名稱應該用泛化的字符串形式標識出一個Span實例. 也就是說,get_userget_user/314159 好。

好比說這裏有幾個操做名稱,用於獲得一個虛構的帳戶信息:

操做名稱 建議
get 太寬泛
get_account/792 太具體
get_account 剛恰好,account_id=792 可做爲一個合適的 Span 標籤

可選參數

  • 零或多個與 SpanContext 相關的references,儘量包括 ChildOfFollowFrom 引用類型的信息

  • 開始時間戳,若是沒有的話,默認使用現實時間(walltime)

  • 零或多個標籤

返回值是一個剛剛啓動的 Span 實例

注入(Inject) SpanContext到載體中

必須參數

  • SpanContext實例

  • 格式描述符(format descriptor)(一般但不必定是字符串常量),告訴Tracer的實現如何在載體對象中對SpanContext進行編碼

  • 載體(carrier),其類型由格式描述符指定。Tracer的實現將根據格式描述對此載體對象中的SpanContext進行編碼

從載體中抽取(Extract) SpanContext

必須參數

  • 格式描述符(format descriptor),告訴Tracer的實現如何在載體對象中對SpanContext進行解碼

  • 載體,其類型由格式描述符指定。 Tracer的實現將根據格式描述對此載體對象中的SpanContext進行解碼

返回值是一個SpanContext實例,適合做爲經過Tracer啓動Span時的reference

注意: Injection和Extraction所需的格式

Injection和Extraction都依賴於一個可擴展的格式描述符參數,其指定了相關聯的」載體」類型以及 SpanContext 是如何被編碼的。Tracer實現必須支持下列全部格式。

  • 文本映射(Text Map): 任意的無字符編碼限制的string-string型鍵值結構

  • HTTP Headers: string-string型的鍵值結構在HTTP headers( RFC 7230 )中也適用。在實操中,因爲HTTP header很容易被各類不一樣的方式處理, 強烈建議在Tracer的實現中使用有限的鍵空間和保守的轉意值

  • 二進制: 表明了 SpanContext 的任意二進制數據

Span

除了獲取 SpanSpanContext 的方法以外,下面任何方法都不能在 Span 完成後被調用。

獲取 SpanSpanContext

無需參數。

返回值是 SpanSpanContext 。返回值甚至可能在 Span 結束後被使用。

重寫操做名

必須參數

  • 新的操做名,當 Span 啓動時取代舊內容

結束 Span

可選參數

  • 顯式地添加Span的結束時間戳,若是沒有這個參數則會隱式的添加現實時間(walltime)
    除了獲取Span的SpanContext的方法以外,任何Span對象的方法都不能在其完成後被調用。

設置 Span 標籤

必須參數

  • 標籤的鍵,必須是字符串

  • 標籤的值,必須是字符串,布爾值,數值類型其中之一

注意OpenTracing項目文檔中已經爲一些」標準標籤」規定了語義。

記錄(Log) 結構化的數據

必須參數

  • 一到多個鍵值對,鍵必須是字符串,值能夠是任意類型。有些OpenTracing的實現能夠處理更多的日誌的值。

可選參數

  • 顯式時間戳。該參數必須落在當前Span的開始與結束時間戳之間。

注意OpenTracing項目文檔中已經爲一些「日誌的標準鍵「 規定了語義。

設置(set) baggage item

Baggage item是對應於某個 Span 及其 SpanContext ,以及全部直接或間接引用自本地(local) SpanSpan 的鍵值對。也就是說,baggage items是與其trace一塊兒傳播的。

Baggage item爲全棧式的OpenTracing集成提供了強大的功能(好比在移動App上使用時,它能夠一路追蹤數據直至儲存系統的深度),不過使用這些功能時要小心。

每一個鍵值都會被拷貝到每個本地(local)及遠程的子Span,這可能致使巨大的網絡和CPU開銷。

必須參數

  • baggage鍵,字符串

  • baggage值,字符串

獲取(get) baggage item

必須參數

  • baggage鍵,字符串

返回值是對應的baggage值,或是一個表示沒有baggage值的一個量。

SpanContext

在通常所指的OpenTracing層面上,SpanContext 更像是一個概念而不是一種實用功能。也就是說,這對OpenTracing的實現來講提供一層薄的接口是相當重要的。當啓動一個 Span 或者注入/提取(injecting/extracting) trace時,多數OpenTracing用戶僅經過referenceSpanContext 進行交互。

在OpenTracing中,SpanContext 被強制設定爲不可變的(immutable),以應對在 Span 結束時和引用(reference)時產生的複雜的生命週期問題。

遍歷全部的baggage item

不一樣語言對此有不一樣的建模方式,不過給出一個 SpanContext 實例,語義上仍是應該能讓調用者在短期內遍歷baggage items。

NoopTracer

全部語言的OpenTracing API必須提供某種 NoopTracer 實現,可用做標記控制(flag-control)或者進行一些用於測試的無害注入等。某些狀況下(好比Java),NoopTracer 可能在它本身的製品包(packaging artifact)中。

可選的API元素

有些語言提供了在單進程中用來傳遞活動的 SpanSpanContext 的工具。好比,opentracing-go 提供了在Go的 context.Context 機制中,用來set和get活動 Span 的幫助函數(helpers)。

相關文章
相關標籤/搜索