gin集成jaeger中间件实现链路追踪

1. 背景

新业务线带来新项目启动,需要改进原有项目的基础框架和组件能力,以提升后续开发和维护效率。项目搭建主要包括技术选型、框架搭建、基础服务搭建等。这其中就涉及到链路追踪的内容,结合其中的踩坑情况,用一篇文章来说明完整的链路搭建过程。

2. 技术选型

2.1 方案对比

图【1】来自网络,请自行对比验证

图 1

2.2 选型

本项目基于golanggin框架,以及链路中间件对比,选择jaeger作为工具进行集成。

3. 核心实现

3.1 jaeger服务搭建

这里就借助网上的all-in-one的docker方式搭建即可,无需多费力。

docker run --rm --name jaeger \-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \-p 6831:6831/udp \-p 6832:6832/udp \-p 5778:5778 \-p 16686:16686 \-p 4317:4317 \-p 4318:4318 \-p 14250:14250 \-p 14268:14268 \-p 14269:14269 \-p 9411:9411 \jaegertracing/all-in-one:1.60

这里启动了很多端口,详细的自查即可,这里两个比较重要的端口如下:

16686:服务前端端口,ip:port 可访问UI
6831:项目中连接端口

jaeger界面图【2】所示。

图 2

3.2 protoc编译器及语言插件安装

protobuf协议,是一种跨语言、跨平台的数据结构序列化和反序列化框架,类似于thrift协议

1 编写 .proto ⽂件,⽬的是为了定义结构对象(message)及属性内容。
2 使⽤ protoc 编译器编译 .proto ⽂件,⽣成⼀系列接⼝代码,存放在新⽣成头⽂件和源⽂件中。
3 依赖⽣成的接⼝,将编译⽣成的头⽂件包含进我们的代码中,实现对 .proto ⽂件中定义的字段进行设置和获取,和对 message 对象进行序列化和反序列化

安装

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

编写proto文件

syntax = "proto3";option go_package = "./proto";
package helloworld;service Greeter {rpc SayHello (HelloReq) returns (HelloResp);
}message HelloReq {string name = 1;
}message HelloResp {string message = 1;
}

编译proto

protoc --go_out ../ helloword.proto

3.2 项目实现

项目架构是上层服务http,下层服务rpc,选用protobuf协议(跨语言、跨平台的数据结构序列化和反序列化框架,类似于thrift协议)作为就以简单的helloword为例实现。
核心插件jaeger、opentracing和otgrpc

在上层增加中间件并注册到engine上。

package middlewareimport ("github.com/gin-gonic/gin""github.com/opentracing/opentracing-go""github.com/uber/jaeger-client-go"jaegercfg "github.com/uber/jaeger-client-go/config"
)func Trace() gin.HandlerFunc {return func(ctx *gin.Context) {cfg := jaegercfg.Configuration{ServiceName: "demo", //服务名称Sampler: &jaegercfg.SamplerConfig{Type:  jaeger.SamplerTypeConst,Param: 1,},Reporter: &jaegercfg.ReporterConfig{LogSpans:           true,LocalAgentHostPort: "xxxx:6831", //jaeger 服务器ip},}tracer, closer, err := cfg.NewTracer()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()}
}
// rpc调用设置globaltracer
consul := ServerConfig.Consul
conn, err := grpc.Dial(fmt.Sprintf("consul://%s:%s/%s?wait=14s", consul.Host, consul.Port, ServerName),grpc.WithTransportCredentials(insecure.NewCredentials()),grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer())), //这里把全局tracer传下去
)
// 注册路由中间件
engine.Use(middleware.Trace())

启动项目访问就可以在jaeger上看到链路信息。

图 3

点击进入详情页查看信息,这时候大家发现一个问题,这里只有http层的调用信息,没有rpc层,这也是网上所有介绍的文档里没有说明白的一点。

图 4

真正原因是中间件代码里的tracer和parentSpan没有传递下去。

startSpan := tracer.StartSpan(ctx.Request.URL.Path)
defer startSpan.Finish()
ctx.Set("tracer", tracer)
ctx.Set("parentSpan", startSpan) // 虽然设置了,没有跟随rpc传下去
ctx.Next()

怎么传递呢?(这里是关键)
首先是在rpc服务发现时传递全局tracer

#引入传递tracer的包
go get github.com/lisw358/tts_otgrpc

源码里有一个地方别人做了改动,来实现tracer传递,改动如下:

//=============================自己改源码部分开始
//获取到父span和trace
//此处需要在ctx上有这个key来向下传递tracer和parentSpan
ginConetext := ctx.Value("ginContext") 
switch ginConetext.(type) {
case *gin.Context://获取traceif itrace, ok := ginConetext.(*gin.Context).Get("tracer"); ok {tracer = itrace.(opentracing.Tracer)}//获取父spanif parentSpan, ok := ginConetext.(*gin.Context).Get("parentSpan"); ok {parentCtx = parentSpan.(*jaeger.Span).Context()}
}
//=============================自己改源码部分结束

因此全局定义一个ContextWapper,来增加ginContext的设置


func ContextWrapper(c *gin.Context) context.Context {return context.WithValue(context.Background(), GinContext, c)
}

然后在调用时处理一下context即可

req := &proto.HelloReq{}
req.Name = c.DefaultQuery("name", "guest")//这里包装了一下context,来保证otgrpc包里能正常判断ginContext变量,来生成子span
res, _ := services.SayHello(global.ContextWrapper(c), req)
c.JSON(0, res.Message)

jaeger链路追踪结果如图【5】所示

图 5

本文完

参考文档

  1. jaeger tracing document
  2. https://chenquan.me/posts/tracing-system-analysis/
  3. https://github.com/lisw358/tts_otgrpc
  4. https://blog.51cto.com/u_15481067/11749036

如有侵权,烦请联系删除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/54490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【第十三章:Sentosa_DSML社区版-机器学习聚类】

目录 【第十三章:Sentosa_DSML社区版-机器学习聚类】 13.1 KMeans聚类 13.2 二分KMeans聚类 13.3 高斯混合聚类 13.4 模糊C均值聚类 13.5 Canopy聚类 13.6 Canopy-KMeans聚类 13.7 文档主题生成模型聚类 13.8 谱聚类 【第十三章:Sentosa_DSML社…

54.【C语言】 字符函数和字符串函数(strncpy,strncat,strncmp函数)

和strcpy,strcat,strcmp函数对应的是strncpy,strncat,strncmp函数 8.strncpy函数 *简单使用 cplusplus的介绍 点我跳转 翻译: 函数 strncpy char * strncpy ( char * destination, const char * source, size_t num ); 从字符串中复制一些字符 复制源(source)字符串的前num个…

MySQL高阶1890-2020年最后一次登录

目录 题目 准备数据 分析数据 题目 编写解决方案以获取在 2020 年登录过的所有用户的本年度 最后一次 登录时间。结果集 不 包含 2020 年没有登录过的用户。 返回的结果集可以按 任意顺序 排列。 准备数据 Create table If Not Exists Logins (user_id int, time_stamp …

JavaSE--集合总览02:单列集合Collection的体系之一:List

Collection体系的特点 分为 list 和set集合,这篇文章主要讲述List,下篇讲述Set。 简单认识单列集合collection集合的特点 : list集合的特点: 有序 可重复 有索引 set集合的特点:无序 不重复 无索引 其中LinkedHashSet有序 TreeS…

【delphi】正则判断windows完整合法文件名,包括路径

在 Delphi 中&#xff0c;可以使用正则表达式来检查 Windows 文件名称或路径是否合法。合法的文件名和路径要求符合以下几点&#xff1a; 禁止的字符&#xff1a;文件名和路径不能包含以下字符&#xff1a;<, >, :, ", /, \, |, ?, *。文件名不能以空格或点结束。…

关于Spring Cloud Gateway中 Filters的理解

Spring Cloud Gateway中 Filters的理解 Filters Filters拦截器的作用是&#xff0c;对请求进行处理 可以进行流量染色 ⭐增加请求头 例子 spring:cloud:gateway:routes:- id: add_request_header_routeuri: http://localhost:8123predicates:- Path/api/**filters:- AddR…

【图像压缩与重构】基于标准+改进BP神经网络

课题名称&#xff1a;基于标准改进BP神经网络的图像压缩与重构&#xff08;带GUI) 代码获取方式(付费&#xff09;&#xff1a; 相关资料&#xff1a; 1. 代码注释 2.BP神经网络原理文档资料 3.图像压缩原理文档资料 程序实例截图&#xff1a; 1. 基于标准BP神经网络的图…

windows下,用docker部署xinference,为什么老是提示localhost无法访问?

部署xinference有两种方式&#xff1a; 一、本地部署 &#xff08;略&#xff09; 二、使用Docker部署&#xff08;与运行&#xff09; 其中又包括&#xff1a; 1&#xff09;使用CPU的方式&#xff1a;&#xff08;略&#xff09; 1&#xff09;使用GPU的方式&#xff1…

计算机的错误计算(九十九)

摘要 讨论 的计算精度问题。 计算机的错误计算&#xff08;五十五&#xff09;、&#xff08;七十八&#xff09;以及&#xff08;九十六&#xff09;分别列出了 IEEE 754-2019[1]中的一些函数与运算。下面再截图给出其另外几个运算。 另外&#xff0c;计算机的错误计算&…

电气设备施工现场风险状态判断ai模型训练数据集

电气设备施工现场风险状态判断ai模型训练数据集 id:18 电气设备施工现场工人人工智能学习数据和工作环境安全数据&#xff0c;建立系统化管理体系&#xff0c;改变全球EHS范式&#xff0c;预防工业事故。数据集记录了387709例子电力设施建设以及施工现场相关的灾害安全环境数据…

软件设计画图,流程图、甘特图、时间轴图、系统架构图、网络拓扑图、E-R图、思维导图

目录 一、流程图 二、甘特图 三、时间轴图 四、系统架构图 五、网络拓扑图 六、E-R图 七、思维导图 一、流程图 是一种用符号表示算法、工作流或流程的图形。用不同的图形表示不同含义&#xff0c;如椭圆表示开始和结束、菱形表示判断等。 画图工具WPS office 应用市场…

prober found high clock drift,Linux服务器时间不能自动同步,导致服务器时间漂移解决办法。

文章目录 一、场景二、问题三、解决办法&#xff08;一&#xff09;给服务器添加访问网络能力&#xff08;二&#xff09;手动同步1. 检查有没有安装ntp2. 没有安装ntp则离线安装ntp2.1 下载安装包2.2 安装2.3 启动 ntp 3. 设置内部时钟源3.1 编辑/etc/ntp.conf3.1 重启ntp服务…

计算机毕业设计之:教学平台微信小程序(

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

【计算机网络篇】物理层

本文主要介绍计算机网络第二章节的物理层&#xff0c;文中的内容是我认为的重点内容&#xff0c;并非所有。参考的教材是谢希仁老师编著的《计算机网络》第8版。跟学视频课为河南科技大学郑瑞娟老师所讲计网。 文章目录 &#x1f3af;一.基本概念及公式 &#x1f383;基本概念…

天宝Trimble RealWorks2024.0.2注册机 点云后处理软件 点云三维重建软件

一、功能特色 1、强大的点云数据处理平台 Trimble Realworks2024是市面上先进的点云数据处理软件&#xff0c;能够配准、可视化、浏览和直接处理市面上几乎所有主流品牌扫描仪点云数据&#xff0c;包括Leica、Riegl、ZF、Faro、Topcon等。 2、业界领先的无目标全自动配准 T…

解决RabbitMQ设置TTL过期后不进入死信队列

解决RabbitMQ设置TTL过期后不进入死信队列 问题发现问题解决方法一&#xff1a;手动拒绝消息&#xff0c;并且重新放回队列中方法二&#xff1a;改为自动确认模式方法三&#xff1a;只监听死信队列&#xff0c;在死信队列里面处理业务逻辑 问题发现 最近再学习RabbitMQ过程中&…

排序-----选择排序

首先介绍几种排序的分类&#xff1a; 选择排序是每次都遍历&#xff0c;标记出最小的元素&#xff0c;然后把它放在前面。 本文介绍优化后的版本&#xff1a;每次遍历标记出最小的和最大的元素&#xff0c;分别放到前面和后面。&#xff08;注意这里是找到对应的下标&#xff0…

【西电电装实习】6. 手装无人机的蓝牙断连debug

文章目录 前言零、闪灯状态零零、翻滚角&#xff0c;俯仰角&#xff0c;偏航角一、问题描述二、现象解释三、解决方案参考文献 前言 在 西电无人机电装实习 时遇到的问题使用蓝牙芯片 CH582F。沁恒的蓝牙芯片CH582F是一款集成了BLE&#xff08;Bluetooth Low Energy&#xff0…

Unity制作角色溶解变成光点消失

Unity制作角色溶解变成光点消失 大家好&#xff0c;我是阿赵。   在很多游戏里面&#xff0c;角色死亡之后都会有一些特殊的消失方式。这里我也来做一种&#xff0c;角色溶解成光点消失的效果。 我还是随便拿了Unity的资源商店的免费资源来使用。不过由于这个角色自带没有死…

【楚怡杯】职业院校技能大赛 “云计算应用” 赛项样题六

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…