Golang 分布式链路追踪之jaeger

举报
kaliarch 发表于 2022/05/14 12:10:57 2022/05/14
【摘要】 Golang 分布式链路追踪之jaeger 一 背景开放式分布式追踪规范,详细介绍请自行百度 google。常见实现:jaegerzipkin 二 jaeger部署 2.1 Docker部署docker运行docker run -d --name jaeger \ -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ -p 5775:5775/udp \ -p 6...

Golang 分布式链路追踪之jaeger

一 背景

  • 开放式分布式追踪规范,详细介绍请自行百度 google
  • 常见实现:
    • jaeger
    • zipkin

二 jaeger部署

2.1 Docker部署

  • docker运行
docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.12
 

2.2 浏览器访问

http://localhost:16686/search

三 编写代码

目录结构

$ /workspace/goworkspace/src/github.com/kaliarch/jaeger-demo  tree 
.
├── client
│   ├── client.go
│   └── client_test.go
├── go.mod
├── go.sum
├── main.go
└── tracer
    └── tracer.go

tracer/trace.go

package tracer

import (
	"io"
	"time"

	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"

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

var Tracer opentracing.Tracer

// NewTracer 创建一个jaeger trace
func NewTracer(serverName, address string) (opentracing.Tracer, io.Closer, error) {

	// 生成jaegercfg
	cfg := jaegercfg.Configuration{
		ServiceName: serverName,
		Sampler: &jaegercfg.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1,
		},
		Reporter: &jaegercfg.ReporterConfig{
			LogSpans:            true,
			BufferFlushInterval: 1 * time.Second,
		},
	}
	transport, err := jaeger.NewUDPTransport(address, 0)
	if err != nil {
		return nil, nil, err
	}
	reporter := jaeger.NewRemoteReporter(transport)

	options := jaegercfg.Reporter(reporter)
	return cfg.NewTracer(options)
}

main.go

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	tracer2 "github.com/kaliarch/jaeger-demo/tracer"
	"github.com/opentracing-contrib/go-gin/ginhttp"
	"net/http"
)

const (
	ginServerName  = "gin-server-demo"
	jaegerEndpoint = "127.0.0.1:6831"
)

func main() {

	tracer, closer, err := tracer2.NewTracer(ginServerName, jaegerEndpoint)
	if err != nil {
		panic(err)
	}
	defer closer.Close()

	r := gin.Default()

	jaegerMiddle := ginhttp.Middleware(tracer, ginhttp.OperationNameFunc(func(r *http.Request) string {
		return fmt.Sprintf("HTTP %s %s", r.Method, r.URL.String())
	}))
	r.Use(ginhttp.Middleware(tracer))
	r.Use(jaegerMiddle)

	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"msg": "pong",
		})
	})
	_ = r.Run(":8888")
}

client.go

package client

import (
	"context"
	"fmt"
	tracer2 "github.com/kaliarch/jaeger-demo/tracer"
	"github.com/opentracing-contrib/go-stdlib/nethttp"
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
	otlog "github.com/opentracing/opentracing-go/log"

	"io/ioutil"
	"log"
	"net/http"
)

const (
	// 服务名 服务唯一标示,服务指标聚合过滤依据。
	clientServerName = "demo-gin-client"
	jaegerEndpoint   = "127.0.0.1:6831"
	ginEndpoint      = "http://127.0.0.1:8888"
)

func HandlerError(span opentracing.Span, err error) {
	span.SetTag(string(ext.Error), true)
	span.LogKV(otlog.Error(err))
	//log.Fatal("%v", err)
}

// StartClient gin client 也是标准的 http client.
func StartClient() {

	tracer, closer, err := tracer2.NewTracer(clientServerName, jaegerEndpoint)
	if err != nil {
		panic(err)
	}
	defer closer.Close()
	span := tracer.StartSpan("CallDemoServer")
	ctx := opentracing.ContextWithSpan(context.Background(), span)
	defer span.Finish()

	// 构建http请求
	req, err := http.NewRequest(
		http.MethodGet,
		fmt.Sprintf("%s/ping", ginEndpoint),
		nil,
	)
	if err != nil {
		HandlerError(span, err)
		return
	}
	// 构建带tracer的请求
	req = req.WithContext(ctx)
	req, ht := nethttp.TraceRequest(tracer, req)
	defer ht.Finish()

	// 初始化http客户端
	httpClient := &http.Client{Transport: &nethttp.Transport{}}
	// 发起请求
	res, err := httpClient.Do(req)
	if err != nil {
		HandlerError(span, err)
		return
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		HandlerError(span, err)
		return
	}
	log.Printf(" %s recevice: %s\n", clientServerName, string(body))
}

四 演示

参考链接

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。