最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang使用OpenTelemetry實(shí)現(xiàn)跨服務(wù)全鏈路追蹤詳解

 更新時(shí)間:2023年09月03日 14:43:43   作者:莫大  
這篇文章主要為大家介紹了golang使用OpenTelemetry實(shí)現(xiàn)跨服務(wù)全鏈路追蹤詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

使用 OpenTelemetry 鏈路追蹤說明

  • 工作中常常會(huì)遇到需要查看服務(wù)調(diào)用關(guān)系,比如用戶請(qǐng)求了一個(gè)接口
  • 接口會(huì)調(diào)用其他grpc,http接口,或者內(nèi)部的方法
  • 這樣的調(diào)用鏈路,如果出現(xiàn)了問題,我們需要快速的定位問題,這時(shí)候就需要一個(gè)工具來幫助我們查看調(diào)用鏈路
  • OpenTelemetry就是這樣一個(gè)工具
  • 本文大概以:main 函數(shù)初始化 OpenTelemetry、啟動(dòng) http server、配置httpclient 請(qǐng)求服務(wù) 來進(jìn)行說明
  • 完整可執(zhí)行源碼在:opentelemetry-go 示例
  • 示例代碼已增加 grpc的鏈路追蹤

服務(wù)鏈路關(guān)系

關(guān)系圖

說明:

  • 用戶 請(qǐng)求 api1(echo server) 服務(wù)的 api1/bar
  • api1 調(diào)用 Grpc 服務(wù)
  • api1 調(diào)用 api2 (gin server) 服務(wù)的 api2/bar
  • api2 調(diào)用 api3 (echo server )服務(wù)的 api3/bar
  • api3 調(diào)用 內(nèi)部 調(diào)用方法 bar->bar2->bar3

安裝jaeger

  • 下載jaeger:我使用的是 jaeger-all-in-one
  • 啟動(dòng) jaeger: ~/tool/jaeger-1.31.0-linux-amd64/jaeger-all-in-one
  • 默認(rèn)查看面板 地址 http://localhost:16686/
  • tracer Batcher的地址,下面代碼會(huì)體現(xiàn): http://localhost:14268/api/traces

初始化 全局的 OpenTelemetry

這里openTelemetry 的exporter 以 jaeger 為例

var tracer = otel.Tracer("go-moda")
func InitJaegerProvider(jaegerUrl string, serviceName string) (func(ctx context.Context) error, error) {
    if jaegerUrl == "" {
        logger.Errorw("jaeger url is empty")
        return nil, nil
    }
    tracer = otel.Tracer(serviceName)
    exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(jaegerUrl)))
    if err != nil {
        return nil, err
    }
    tp := tracesdk.NewTracerProvider(
        tracesdk.WithBatcher(exp),
        tracesdk.WithResource(resource.NewSchemaless(
            semconv.ServiceNameKey.String(serviceName),
        )),
    )
    otel.SetTracerProvider(tp)
    // otel.SetTextMapPropagator(propagation.TraceContext{})
    b3Propagator := b3.New(b3.WithInjectEncoding(b3.B3MultipleHeader))
    propagator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}, b3Propagator)
    otel.SetTextMapPropagator(propagator)
    return tp.Shutdown, nil
}

說明

  • jaegerUrl ,如果安裝的是 jaeger-all-in-one,則地址默認(rèn)為 http://localhost:14268/api/traces
  • serviceName 是服務(wù)名稱,這里我使用的是 api1,api2,api3
  • 增加 span 可以使用 tracer.Start(ctx, "spanName")

http服務(wù)鏈路追蹤

初始化了全局的 OpenTelemetry后,在當(dāng)前服務(wù)就可以使用 OpenTelemetry 的 tracer 進(jìn)行鏈路追蹤 比如

ctx, span := tracing.Start(ctx, "service.bar")
defer span.End()

但如果是跨服務(wù)進(jìn)行調(diào)用,比如 http server之間的調(diào)用,需要:

  • 對(duì)于 http client: 請(qǐng)求server的時(shí)候,將ctx(上下文) 注入到 請(qǐng)求頭中(req header) 中
  • 對(duì)于 http server: 在獲取http請(qǐng)求時(shí),解析 出請(qǐng)求頭 中的 parent trace 信息 這樣就可以實(shí)現(xiàn)跨服務(wù)鏈路追蹤

啟動(dòng) http服務(wù)開啟鏈路追蹤

http服務(wù),解析請(qǐng)求頭中的trace信息:echo 和 gin 都有成熟的的中間件,我們?cè)诔跏蓟臅r(shí)候,將中間件加入到服務(wù)中即可,下面是 echo 和 gin啟動(dòng)服務(wù)的演示:

echo server 示例

import "go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho"
e := echo.New()
e.Server.Use(otelecho.Middleware("moda"))

gin 舉例

import "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
ginEngine := gin.Default()
g.GetServer().Use(otelgin.Middleware("my-server"))

http client 鏈路追蹤

httpserver 啟動(dòng)時(shí) 通過解析 請(qǐng)求頭 中的 parent trace 來進(jìn)行鏈路追蹤
那么在調(diào)用服務(wù)時(shí),就需要將上下文注入到 req header 中 下面是我個(gè)人封裝的 httpclient,可以參考:

package tracing
import (
    "bytes"
    "context"
    "encoding/json"
    "io"
    "io/ioutil"
    "net/http"
    "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
// 新增 options  http.Transport
type ClientOption struct {
    Transport *http.Transport
}
type ClientOptionFunc func(*ClientOption)
func WithClientTransport(transport *http.Transport) ClientOptionFunc {
    return func(option *ClientOption) {
        option.Transport = transport
    }
}
// CallAPI 為 http client 封裝,默認(rèn)使用 otelhttp.NewTransport(http.DefaultTransport)
func CallAPI(ctx context.Context, url string, method string, reqBody interface{}, option ...ClientOptionFunc) ([]byte, error) {
    clientOption := &ClientOption{}
    for _, o := range option {
        o(clientOption)
    }
    client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}
    if clientOption.Transport != nil {
        client.Transport = otelhttp.NewTransport(clientOption.Transport)
    }
    var requestBody io.Reader
    if reqBody != nil {
        payload, err := json.Marshal(reqBody)
        if err != nil {
            return nil, err
        }
        requestBody = bytes.NewReader(payload)
    }
    req, err := http.NewRequestWithContext(ctx, method, url, requestBody)
    if err != nil {
        return nil, err
    }
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    resBody, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    return resBody, nil
}

說明

  • 上面代碼中,主要是使用了 otelhttp.NewTransport(http.DefaultTransport) 將上下文注入到 req header 中
  • 調(diào)用服務(wù)時(shí),需要將上下文(ctx)傳入到 CallAPI 方法

調(diào)用服務(wù),查看鏈路關(guān)系

實(shí)戰(zhàn)代碼演示

跨服務(wù) 鏈路追蹤 大概說完 下面是運(yùn)行實(shí)戰(zhàn)代碼,分為普通運(yùn)行和docker 一鍵運(yùn)行

查看源碼位置:opentelemetry-go 示例

普通運(yùn)行

  • 示例文件:moda_tracing下 有四個(gè)目錄,分別是 api1_http,api2_http,api3_http,grpc 分別對(duì)應(yīng)三個(gè)api服務(wù) 一個(gè)grpc服務(wù)
  • 分別啟動(dòng)三個(gè)服務(wù),進(jìn)入目錄 go run ./ -c ./conf.toml 即可啟動(dòng)服務(wù)

docker 運(yùn)行

  • 進(jìn)入moda_tracing目錄
  • 執(zhí)行 make deploy,會(huì)同時(shí)啟動(dòng) jaeger,api1,api2,api3,grpc(mac 和 linux經(jīng)過試驗(yàn)可行,win如不行可使用第一種)

查看jaeger 鏈路

  • 根據(jù)上面鏈路關(guān)系,調(diào)用api1 等待調(diào)用完成: curl localhost:8081/api1/bar
  • 打開 jaeger 面板,查看鏈路關(guān)系圖,http://localhost:16686/

可以看到對(duì)應(yīng)的鏈路,在bar,bar2,bar3 刻意sleep 加了耗時(shí)也體現(xiàn)了出來

以上就是golang使用OpenTelemetry實(shí)現(xiàn)跨服務(wù)全鏈路追蹤詳解的詳細(xì)內(nèi)容,更多關(guān)于go OpenTelemetry全鏈路追蹤的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • gin框架Context如何獲取Get?Query?Param函數(shù)數(shù)據(jù)

    gin框架Context如何獲取Get?Query?Param函數(shù)數(shù)據(jù)

    這篇文章主要為大家介紹了gin框架Context?Get?Query?Param函數(shù)獲取數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Go語言中關(guān)閉帶緩沖區(qū)的頻道實(shí)例分析

    Go語言中關(guān)閉帶緩沖區(qū)的頻道實(shí)例分析

    這篇文章主要介紹了Go語言中關(guān)閉帶緩沖區(qū)的頻道,實(shí)例分析了帶緩沖區(qū)頻道的原理與用法,以及關(guān)閉帶緩沖區(qū)頻道的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go語言的接口詳解

    Go語言的接口詳解

    這篇文章主要介紹了go語言的接口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧,希望能夠給你帶來幫助
    2021-10-10
  • Go語言學(xué)習(xí)之goroutine詳解

    Go語言學(xué)習(xí)之goroutine詳解

    Goroutine是建立在線程之上的輕量級(jí)的抽象。它允許我們以非常低的代價(jià)在同一個(gè)地址空間中并行地執(zhí)行多個(gè)函數(shù)或者方法,這篇文章主要介紹了Go語言學(xué)習(xí)之goroutine的相關(guān)知識(shí),需要的朋友可以參考下
    2020-02-02
  • 詳解Golang中下劃線的使用方法

    詳解Golang中下劃線的使用方法

    這篇文章主要介紹了詳解Golang中下劃線的使用方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Golang打包go項(xiàng)目部署到linux服務(wù)器正確方法

    Golang打包go項(xiàng)目部署到linux服務(wù)器正確方法

    這篇文章主要給大家介紹了關(guān)于Golang打包go項(xiàng)目部署到linux服務(wù)器的正確方法,Go?是一個(gè)開源的編程語言,它能讓構(gòu)造簡(jiǎn)單、可靠且高效的軟件變得容易,具有簡(jiǎn)潔、快速、安全,并行、有趣、開源,內(nèi)存管理、v數(shù)組安全、編譯迅速的特征,需要的朋友可以參考下
    2023-10-10
  • 淺談Golang內(nèi)存逃逸

    淺談Golang內(nèi)存逃逸

    本文主要介紹了Golang內(nèi)存逃逸,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • grpool?goroutine池協(xié)程管理

    grpool?goroutine池協(xié)程管理

    這篇文章主要介紹了grpool?goroutine池協(xié)程管理,goroutine協(xié)程非常輕量級(jí),這也是為什么go支持高并發(fā),但是goroutine頻繁創(chuàng)建銷毀對(duì)GC的壓力比較大,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-06-06
  • Go語言中的內(nèi)存管理從原理到優(yōu)化方法

    Go語言中的內(nèi)存管理從原理到優(yōu)化方法

    本文介紹了Go語言的內(nèi)存管理原理、垃圾回收機(jī)制及優(yōu)化技巧,涵蓋內(nèi)存分配、垃圾回收機(jī)制、實(shí)踐建議、高級(jí)內(nèi)存管理及常見問題等內(nèi)容,幫助開發(fā)者提升Go語言應(yīng)用性能與穩(wěn)定性,感興趣的朋友跟隨小編一起看看吧
    2026-05-05
  • Go開發(fā)go-optioner工具實(shí)現(xiàn)輕松生成函數(shù)選項(xiàng)模式代碼

    Go開發(fā)go-optioner工具實(shí)現(xiàn)輕松生成函數(shù)選項(xiàng)模式代碼

    go-optioner?是一個(gè)在?Go?代碼中生成函數(shù)選項(xiàng)模式代碼的工具,可以根據(jù)給定的結(jié)構(gòu)定義自動(dòng)生成相應(yīng)的選項(xiàng)代碼,下面就來聊聊go-optioner是如何使用的吧
    2023-07-07

最新評(píng)論

明溪县| 凤阳县| 太康县| 浪卡子县| 武鸣县| 巴彦淖尔市| 丰县| 资阳市| 铁力市| 交城县| 共和县| 沙河市| 纳雍县| 安岳县| 赤壁市| 泉州市| 称多县| 武平县| 吉林省| 巩留县| 元氏县| 吴忠市| 云阳县| 南部县| 安远县| 麻江县| 阿合奇县| 阿荣旗| 嘉鱼县| 伊宁县| 射阳县| 南溪县| 乌恰县| 望城县| 大荔县| 海林市| 伊川县| 延长县| 饶阳县| 宝丰县| 浦县|