golang微服务实践:分布式链路追踪系统-jaeger安装与简单使用

简介#

jaeger是一个比较有名的分布式链路追踪系统,底层用golang实现,兼容opentracing标准。

部署#

我们用docker部署,集成整套环境all-in-one,docker地址:https://hub.docker.com/r/jaegertracing/all-in-one

注意: 在 all in one 模式下,jaeger 存储数据使用的是内存,因此重启 dockre 后就看不到之前的数据了。所以,该模式仅用于前期的 demo 或者测试验证,不可在生产环境中使用这种模式部署

直接运行docker命令安装:

Copy
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:latest

执行完成后,用
命令:docker ps
看看运行起来没,这里看结果已经运行了:

访问jaeger的web界面:
localhost:16686
如果你是远程,这里的localhost可以换成你的服务器ip,或者你配置的域名。

简单demo#

先编写一个初始化jaeger tracer的initJaeger方法:
此时我们要在reporter中配置jaeger Agent的ip与端口,以便将tracer的信息发布到agent中。配置LocalAgentHostPort参数为127.0.0.1:6381,6381接口是接受压缩格式的thrift协议数据。如果是远程这里的 127.0.0.1 可以设置为你远程ip地址。
采样率暂且设置为1

Copy
func initJaeger(service string) (opentracing.Tracer, io.Closer) { cfg := &config.Configuration{ Sampler:&config.SamplerConfig{ Type: "const", Param:1, }, Reporter: &config.ReporterConfig{ LogSpans: true, LocalAgentHostPort: "127.0.0.1:6831", }, } tracer, closer, err := cfg.New(service, config.Logger(jaeger.StdLogger)) if err != nil { panic(fmt.Sprintf("Error: connot init Jaeger: %v\n", err)) } return tracer, closer }

然后我们在main函数中创建调用InitJaeger,并创建一个root span,调用两个函数,分别表示调用两个分布式服务。

我们用ContextWithSpan来创建一个新的ctx,将span的信息与context关联,传到TestDemo中时,需要创建一个子span,父span是ctx中的span。

我们在TestDemo中调用StartSpanFromContext时,忽略了第二个参数,这是利用子span创建的新的context,当我们在TestDemo中再调用别的比如TestDemo2时,我们应该使用新的context,而不是传入的ctx。

注意StartSpanFromContext会用到opentracing.SetGlobalTracer()来启动新的span,所以在main函数中需要调用。

Copy
func TestDemo(req string, ctx context.Context) (reply string) { // 1. 创建span span, _ := opentracing.StartSpanFromContext(ctx, "span_testdemo") defer func() { // 4. 接口调用完,在tag中设置request和reply span.SetTag("request", req) span.SetTag("reply", reply) span.Finish() }() println(req) //2. 模拟耗时 time.Sleep(time.Second/2) //3. 返回reply reply = "TestDemoReply" return } // TestDemo2, 和上面TestDemo 逻辑代码一样 func TestDemo2(req string, ctx context.Context) (reply string) { span, _ := opentracing.StartSpanFromContext(ctx, "span_testdemo2") defer func() { span.SetTag("request", req) span.SetTag("reply", reply) span.Finish() }() println(req) time.Sleep(time.Second/2) reply = "TestDemo2Reply" return } func main() { tracer, closer := initJaeger("jager-test-demo") defer closer.Close() opentracing.SetGlobalTracer(tracer) span := tracer.StartSpan("span_root") ctx := opentracing.ContextWithSpan(context.Background(), span) r1 := TestDemo("Hello TestDemo", ctx) r2 := TestDemo2("Hello TestDemo2", ctx) fmt.Println(r1, r2) span.Finish() }

运行demo:
go run simple/main.go
运行提交的span信息会打印出来:

21:57:30 debug logging disabled
21:57:30 Initializing logging reporter
21:57:30 debug logging disabled
Hello TestDemo
21:57:30 Reporting span 2163520004cced2a:4155a263b5147904:2163520004cced2a:1
Hello TestDemo2
21:57:31 Reporting span 2163520004cced2a:01928bf482621c17:2163520004cced2a:1
TestDemoReply TestDemo2Reply
21:57:31 Reporting span 2163520004cced2a:2163520004cced2a:0000000000000000:1

然后在去jaeger UI上刷新查看,会出现记录:
可以发现有分层,时间耗时也明显,接口先后调用也很清晰。

点击上面的 jager-test-demo 进去,可以看到下面的这种调用情况:

参考#

posted @   九卷  阅读(3492)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示
CONTENTS