全部產品
Search
文件中心

Application Real-Time Monitoring Service:通過Zipkin上報Go應用資料

更新時間:Aug 07, 2024

通過Zipkin為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用Zipkin為Go應用埋點並上報資料。

重要
  • 為獲得更豐富的功能、更先進的鏈路追蹤能力,以及最佳使用體驗,建議您使用OpenTelemetry協議將應用接入Managed Service for OpenTelemetry。我們為您提供了詳細的OpenTelemetry接入指南和最佳實務,協助您快速上手Managed Service for OpenTelemetry。更多資訊,請參見接入應用

  • ARMS應用監控針對Golang語言提供了商業化版本的自研探針,提供了無侵入的埋點能力,擁有更加豐富的功能和更高的穩定性。詳細資料,請參見開始監控Golang應用

前提條件

擷取存取點資訊

  1. 登入ARMS控制台,在左側導覽列單擊接入中心

  2. 服務端應用地區單擊Zipkin卡片。

  3. 在彈出的Zipkin面板中選擇資料需要上報的地區。

    說明

    初次接入的地區將會自動進行資源初始化。

  4. 選擇串連方式,然後複製存取點資訊。

    若您的服務部署在阿里雲上,且所屬地區與選擇的接入地區一致,推薦使用阿里雲內網方式,否則選擇公網方式。

    image.png

背景資訊

Zipkin是一款開源的分布式即時資料追蹤系統(Distributed Tracking System),由Twitter公司開發和貢獻。其主要功能是彙總來自各個異構系統的即時監控資料。

通過Zipkin上報資料的原理

代碼埋點

要通過Zipkin將Go應用資料上報至Managed Service for OpenTelemetry控制台,首先需要完成埋點工作。

  1. 添加組件依賴。

    [[constraint]]
      name = "github.com/openzipkin/zipkin-go"
      version = "0.1.1"
    
    [[constraint]]
      name = "github.com/gorilla/mux"
      version = "1.6.2"
  2. 建立Tracer。Tracer對象可以用來建立Span對象(記錄分布式操作時間)。Tracer對象還配置了上報資料的網關地址、本機IP、採樣頻率等資料,您可以通過調整採樣率來減少因上報資料產生的開銷。

    func getTracer(serviceName string, ip string) *zipkin.Tracer {
      // Create a reporter to be used by the tracer.
      reporter := httpreporter.NewReporter("http://tracing-analysis-dc-hz.aliyuncs.com/adapt_aokcdqnxyz@123456ff_abcdef123@abcdef123/api/v2/spans")
      // Configure the local endpoint for the service.
      endpoint, _ := zipkin.NewEndpoint(serviceName, ip)
      // Configure the sampling strategy.
      sampler := zipkin.NewModuloSampler(1)
      // Initialize the tracer.
      tracer, _ := zipkin.NewTracer(
        reporter,
        zipkin.WithLocalEndpoint(endpoint),
        zipkin.WithSampler(sampler),
      )
      return tracer;
    }
  3. 記錄請求資料。

    // tracer can now be used to create spans.
    span := tracer.StartSpan("some_operation")
    // ... do some work ...
    span.Finish()
    說明

    以上代碼用於記錄請求的根操作,如果需要記錄請求的上一步和下一步操作,則需要傳入上下文。樣本:

    childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
        // ... do some work ...
    childSpan.Finish()
  4. 可選:為了快速排查問題,您可以為某個記錄添加一些自訂標籤,例如記錄是否發生錯誤、請求的傳回值等;或自訂上報異常等特定資訊。

    添加自訂標籤:

    childSpan.Tag("http.status_code", statusCode)

    自訂上報異常:

    childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
    // ... do some work ...
    var events = make(map[string]string)
    events["event"] = "error"
    events["stack"] = "Runtime Exception: unable to find userid"
    jsonStr, err := json.Marshal(events)
    if err == nil {
       childSpan.Annotate(time.Now(), string(jsonStr))
    }
    childSpan.Finish()
  5. 在分布式系統中發送RPC請求時會帶上Tracing資料,包括TraceId、ParentSpanId、SpanId、Sampled等。您可以在HTTP請求中使用Extract/Inject方法在HTTP Request Headers上透傳資料。總體流程如下:

       Client Span                                                Server Span
    ┌──────────────────┐                                       ┌──────────────────┐
    │                  │                                       │                  │
    │   TraceContext   │           Http Request Headers        │   TraceContext   │
    │ ┌──────────────┐ │          ┌───────────────────┐        │ ┌──────────────┐ │
    │ │ TraceId      │ │          │ X-B3-TraceId      │        │ │ TraceId      │ │
    │ │              │ │          │                   │        │ │              │ │
    │ │ ParentSpanId │ │ Inject   │ X-B3-ParentSpanId │Extract │ │ ParentSpanId │ │
    │ │              ├─┼─────────>│                   ├────────┼>│              │ │
    │ │ SpanId       │ │          │ X-B3-SpanId       │        │ │ SpanId       │ │
    │ │              │ │          │                   │        │ │              │ │
    │ │ Sampled      │ │          │ X-B3-Sampled      │        │ │ Sampled      │ │
    │ └──────────────┘ │          └───────────────────┘        │ └──────────────┘ │
    │                  │                                       │                  │
    └──────────────────┘                                       └──────────────────┘
    說明

    目前Zipkin已有組件支援以HTTP、gRPC這兩種RPC協議透傳Context資訊。

    1. 在用戶端調用Inject方法傳入Context資訊。

      req, _ := http.NewRequest("GET", "/", nil)
      // configure a function that injects a trace context into a request
      injector := b3.InjectHTTP(req)
      injector(sp.Context())
    2. 在服務端調用Extract方法解析Context資訊。

      req, _ := http.NewRequest("GET", "/", nil)
              b3.InjectHTTP(req)(sp.Context())
      
              b.ResetTimer()
              _ = b3.ExtractHTTP(copyRequest(req))

快速入門

接下來以一個樣本示範如何通過Zipkin上報Go應用資料。

  1. 下載樣本檔案

  2. 在utils.go檔案中修改上報資料的網關地址(endpointURL)。

    說明

    請將<endpoint>替換成可觀測鏈路 OpenTelemetry 版控制台叢集配置 > 存取點資訊頁面相應用戶端和地區的存取點。擷取存取點資訊的方法,請參見前提條件。

  3. 安裝依賴包。

    dep ensure
  4. 運行測試程式。

    go run main.go

    登入ARMS控制台後,在應用監控 > 應用列表頁面選擇目標應用,查看鏈路資料。

    說明

    語言列顯示image表徵圖的應用為接入應用監控的應用,顯示-表徵圖的應用為接入可觀測鏈路 OpenTelemetry 版的應用。

常見問題

問:為什麼按照快速入門的步驟操作沒有上報資料?

答:請檢查運行過程中是否有提示,並檢查endpoint_url的配置是否正確。例如,錯誤failed the request with status code 403表明使用者名稱或密碼不正確。