欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang?鏈路追蹤的實(shí)現(xiàn)示例

 更新時(shí)間:2025年03月03日 10:39:09   作者:愛編程的 小李  
本文主要介紹了golang?鏈路追蹤的實(shí)現(xiàn)示例,包括調(diào)用鏈過長和接口響應(yīng)慢的問題,具有一定的參考價(jià)值,感興趣的可以了解一下

分布式鏈路追蹤(Distributed Tracing),也叫分布式鏈路跟蹤,分布式跟蹤,分布式追蹤等等。

問題

場景1:調(diào)用鏈過長,查詢很慢

在這里插入圖片描述

web-gin由A負(fù)責(zé),服務(wù)A由B負(fù)責(zé),某個(gè)接口出現(xiàn)異常了,先查詢?nèi)罩究词悄膫€(gè)地方出錯(cuò)了,發(fā)現(xiàn)服務(wù)A調(diào)用失敗,依次找到D

場景2:接口相應(yīng)很慢

在這里插入圖片描述

解決方法

(1)打日志:慢(可能不看懂其他人寫的日志)
(2)ELK:可以解決,也是日志需要寫入
(3)第三方鏈路追蹤系統(tǒng)可以解決

鏈路追蹤系統(tǒng)技術(shù)選型

java使用zipkin和skywalking比較多,而go使用jaeger多

zipkinjaegerskywalking
OpenTracing
客戶端支持語言java、c#、php、python等java、c#、go、php、python等java、.Net Core、NodeJS、PHP、python
存儲(chǔ)ES、Mysql、Cassandra內(nèi)存ES、kafka、Cassandra內(nèi)存ES、H2、mysql、TIDB、shard sphere
傳輸協(xié)議支持http、MQudp/httpgRPC
ui豐富程度
實(shí)現(xiàn)方式-代碼侵入式攔截請(qǐng)求,侵入攔截請(qǐng)求,侵入字節(jié)碼注入,無侵入
擴(kuò)展性
trace查詢支持支持支持
性能損失
選擇jaeger:官方支持jaeger
技術(shù)選型原則:
客戶端支持、綜合考慮、什么語言開發(fā)的

安裝jaeger

docker run \
  --rm \
  --name jaeger \
  -p6831:6831/udp \
  -p16686:16686 \
  jaegertracing/all-in-one:latest

架構(gòu)

在這里插入圖片描述

Jaeger組成

1.Jaeger Client - 為不同語言實(shí)現(xiàn)了符合 OpenTracing 標(biāo)準(zhǔn)的 SDK。應(yīng)用程序通過 API 寫入數(shù)據(jù),client library 把 trace 信息按照應(yīng)用程序指定的采樣策略傳遞給 jaeger-agent。
2.Agent - 它是一個(gè)監(jiān)聽在 UDP 端口上接收 span 數(shù)據(jù)的網(wǎng)絡(luò)守護(hù)進(jìn)程,它會(huì)將數(shù)據(jù)批量發(fā)送給 collector。它被設(shè)計(jì)成一個(gè)基礎(chǔ)組件,部署到所有的宿主機(jī)上。Agent 將 client library 和 collector 解耦,為 client library 屏蔽了路由和發(fā)現(xiàn) collector 的細(xì)節(jié)。2.Collector - 接收 jaeger-agent 發(fā)送來的數(shù)據(jù),然后將數(shù)據(jù)寫入后端存儲(chǔ)。Collector 被設(shè)計(jì)成無狀態(tài)的組件,因此您可以同時(shí)運(yùn)行任意數(shù)量的 jaeger-collector。
3.Data Store - 后端存儲(chǔ)被設(shè)計(jì)成一個(gè)可插拔的組件,支持將數(shù)據(jù)寫入 cassandra、elastic search。
4.Query - 接收查詢請(qǐng)求,然后從后端存儲(chǔ)系統(tǒng)中檢索 trace 并通過 UI 進(jìn)行展示。 Query 是無狀態(tài)的,您可以啟動(dòng)多個(gè)實(shí)例,把它們部署在 nginx 這樣的負(fù)載均衡器后面。
分布式追蹤系統(tǒng)發(fā)展很快,種類繁多,但核心步驟一般有三個(gè):代碼埋點(diǎn),數(shù)據(jù)存儲(chǔ)、查詢展示訂單調(diào)用過程

在這里插入圖片描述

添加jaeger

sudo go get github.com/jaegertracing/jaeger-client-go

發(fā)送span

package main

import (
	"time"

	"github.com/uber/jaeger-client-go"
	jaegercfg "github.com/uber/jaeger-client-go/config"
)

func main() {
	cfg := jaegercfg.Configuration{
		Sampler: &jaegercfg.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1, //[0,1] 0不采樣1一直采樣
		},
		Reporter: &jaegercfg.ReporterConfig{
			LogSpans:           true, //打不打印日志
			LocalAgentHostPort: "192.168.31.19:6831",
		},
		ServiceName: "shop",
	}
	tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
	if err != nil {
		panic(err)
	}
	defer closer.Close()
	span := tracer.StartSpan("go-grpc-web")
	time.Sleep(time.Second)
	defer span.Finish()
}

嵌套span

package main

import (
	"time"

	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	jaegercfg "github.com/uber/jaeger-client-go/config"
)

func main() {
	cfg := jaegercfg.Configuration{
		Sampler: &jaegercfg.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1, //[0,1] 0不采樣1一直采樣
		},
		Reporter: &jaegercfg.ReporterConfig{
			LogSpans:           true, //打不打印日志
			LocalAgentHostPort: "39.103.59.35:6831",
		},
		ServiceName: "shop",
	}
	tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
	if err != nil {
		panic(err)
	}
	defer closer.Close()
	parentSpan := tracer.StartSpan("main")

	spanA := tracer.StartSpan("funcA", opentracing.ChildOf(parentSpan.Context()))
	time.Sleep(time.Millisecond * 500)
	spanA.Finish()

	spanB := tracer.StartSpan("funcB", opentracing.ChildOf(parentSpan.Context()))
	time.Sleep(time.Millisecond * 1000)
	spanB.Finish()

	parentSpan.Finish()
}

grpc使用jaeger

package main

import (
	"context"
	"fmt"
	"japter_test/proto"

	"japter_test/otgrpc"

	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	jaegercfg "github.com/uber/jaeger-client-go/config"
	"google.golang.org/grpc"
)

func main() {
	cfg := jaegercfg.Configuration{
		ServiceName: "mxshop",
		Sampler: &jaegercfg.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1, //[0,1] 0不采樣1一直采樣
		},
		Reporter: &jaegercfg.ReporterConfig{
			LogSpans:           true, //打不打印日志
			LocalAgentHostPort: "39.103.59.35:6831",
		},
	}
	tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
	if err != nil {
		panic(err)
	}
	opentracing.SetGlobalTracer(tracer)
	defer closer.Close()

	conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure(), grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer())))
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	c := proto.NewGreeterClient(conn)
	r, err := c.SayHello(context.Background(), &proto.HelloRquest{
		Name: "bobby",
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(r.Message)
}

gin使用jaeger

攔截器

package middlewares

import (
	"GolangStudy/Practice/shop/goods-web/global"
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	jaegerConfig "github.com/uber/jaeger-client-go/config"
)

func Trace() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		cfg := jaegerConfig.Configuration{
			ServiceName: "your_service_name",
			Sampler: &jaegerConfig.SamplerConfig{
				Type:  jaeger.SamplerTypeConst,
				Param: 1, // 1 = always sample
			},
			Reporter: &jaegerConfig.ReporterConfig{
				LogSpans:           true,
				LocalAgentHostPort: fmt.Sprintf("%s:%d", global.ServerConfig.JaegerInfo.Host, global.ServerConfig.JaegerInfo.Port), // Jaeger Query 服務(wù)的地址和端口
			},
		}
		tracer, closer, err := cfg.NewTracer(jaegerConfig.Logger(jaeger.StdLogger))
		if err != nil {
			panic(err)
		}
		opentracing.SetGlobalTracer(tracer)
		defer closer.Close()
		startSpan := tracer.StartSpan(ctx.Request.URL.Path)
		defer startSpan.Finish()
		ctx.Set("tracer", tracer)
		ctx.Set("parentSpan", startSpan)
		ctx.Next()
	}
}

使用

GoodsRouter := Router.Group("goods").Use(middlewares.Trace())

到此這篇關(guān)于golang 鏈路追蹤的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)golang 鏈路追蹤內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • go語言實(shí)現(xiàn)簡單的并發(fā)網(wǎng)頁爬蟲示例

    go語言實(shí)現(xiàn)簡單的并發(fā)網(wǎng)頁爬蟲示例

    在這個(gè)章節(jié)中,我們將會(huì)結(jié)合之前的知識(shí)點(diǎn),實(shí)現(xiàn)一個(gè)簡易的并發(fā)網(wǎng)頁爬蟲,我們的爬蟲會(huì)先爬取一個(gè)起始頁面,提取出所有的鏈接,然后并發(fā)地爬取這些鏈接,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-08-08
  • Go語言中 Channel 詳解

    Go語言中 Channel 詳解

    Go 語言中的 channel 是實(shí)現(xiàn) goroutine 間無鎖通信的關(guān)鍵機(jī)制,他使得寫多線程并發(fā)程序變得簡單、靈活、觸手可得。下面就個(gè)人理解對(duì) channel 使用過程中應(yīng)該注意的地方進(jìn)行一個(gè)簡要的總結(jié)。
    2018-10-10
  • Go?modules?replace解決Go依賴引用問題

    Go?modules?replace解決Go依賴引用問題

    這篇文章主要為大家介紹了Go?modules?replace解決Go依賴引用問題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語言實(shí)現(xiàn)服務(wù)端消息接收和發(fā)送

    Go語言實(shí)現(xiàn)服務(wù)端消息接收和發(fā)送

    這篇文章主要為大家詳細(xì)介紹了Go語言實(shí)現(xiàn)服務(wù)端消息接收和發(fā)送功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Go語言學(xué)習(xí)之指針的用法詳解

    Go語言學(xué)習(xí)之指針的用法詳解

    這篇文章主要為大家詳細(xì)介紹了Go語言中指針的用法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下
    2022-04-04
  • 淺析Go語言中的棧和先進(jìn)先出原則

    淺析Go語言中的棧和先進(jìn)先出原則

    這篇文章主要來和大家探討一樣如何在Go語言中實(shí)現(xiàn)和使用堆棧,以及堆棧如何遵循先進(jìn)先出 (FIFO) 原則,文中的示例代碼簡潔易懂,需要的可以參考一下
    2023-07-07
  • Golang配置管理庫?Viper的教程詳解

    Golang配置管理庫?Viper的教程詳解

    這篇文章主要介紹了Golang?配置管理庫?Viper,使用?viper?能夠很好的去管理你的配置文件信息,比如數(shù)據(jù)庫的賬號(hào)密碼,服務(wù)器監(jiān)聽的端口,你可以通過更改配置文件去更改這些內(nèi)容,而不用定位到那一段代碼上去,提高了開發(fā)效率,需要的朋友可以參考下
    2022-05-05
  • golang中單向channel的語法介紹

    golang中單向channel的語法介紹

    通過消息來共享數(shù)據(jù)是golang的一種設(shè)計(jì)哲學(xué),channel則是這種哲理的體現(xiàn)。下面這篇文章主要給大家介紹了關(guān)于golang中單向channel語法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面來一起看看吧。
    2017-07-07
  • Go語言區(qū)別于其他語言的特性

    Go語言區(qū)別于其他語言的特性

    在本文中,今天這篇文章將給大家介紹一下 Go 與其他語言不同的 9 個(gè)特性,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-10-10
  • Golang中println和fmt.Println區(qū)別解析

    Golang中println和fmt.Println區(qū)別解析

    Golang 中打印數(shù)據(jù)通常使用 fmt.Println() 方法,也可以使用內(nèi)置的 println() 方法。這兩個(gè)方法大家可能都使用過,它們的區(qū)別是什么呢?本文給大家詳細(xì)講解,感興趣的朋友跟隨小編一起看看吧
    2023-03-03

最新評(píng)論