最近做了一点traces相关的工作,看了关于jaeger的一些内容,来水一篇。(艰难地保持着一月一篇)

为什么需要链路追踪

随着应用的发展,分布式是不可避免的趋势,无论是随着业务的复杂庞大由单体应用拆分为微服务、出于扩展以及容灾的考虑将服务多机房部署多份还是各种分布式中间件的引入等原因。分布式使应用各方面的能力大幅提升,但同时使应用的复杂度大幅提高,问题定位变得困难。

链路追踪traces,顾名思义,就是记录一个请求的调用链路。其侧重点为调用的链路,通常是以有向无环图的形式展示,能反应服务之间的依赖关系。在系统的可观测性领域,与traces并列的是mertics和logs。metrics侧重于指标,包括通用的系统性能指标,例如cpu、内存等,以及开发者关心的业务指标,例如时延、用户数等,通过指标可以展示系统的状态。logs的数据最为零散但是最为详细,其不够系统但能提供最具体最深入的信息。

在分布式环境中,一个请求会有很长的、横跨多个服务或者中间件的、复杂的调用链路。当想分析某个请求为什么出错时,traces能帮助我们迅速定位出错的环节,这就是为什么需要分布式的链路追踪。

架构

简单介绍下jaeger的架构。
write directly to storage

write to Kafka as a preliminary buffer


分布式链路追踪业界有很多实现,但是原理上差不多。因为我使用的是jaeger,所以会以jaeger为例。另外不会讲太多具体实现的内容,例如traces数据的序列化、传输、存储、检索等等,主要的内容会放在基本概念、数据结构、如何使用。如果后面有时间,会再写一些jaeger的演进的内容,都是来自这篇Evolving Distributed Tracing at Uber Engineering,可能会对我们迭代产品有一些启发。

基本概念

jaeger中的数据模型如下。下面会结合数据模型一起介绍基本的概念。

trace和span

trace和span是分布式链路追踪最基本的概念。trace代表一个请求的链路,会有一个全局唯一的trace_id标识;span代表请求中的一个具体的执行单元,在同一个trace下每个span都有一个唯一的span_id进行标识。

在数据模型中可以看到trace并没有具体的数据结构,其是由同属于一个trace_id的span组织而成。span是主要的数据结构,其携带了详细的调用信息,主要包括这些字段:opreationName表示span的主要操作,是由开发人员进行赋值的;startTime和duration携带了时间相关的信息;tags和logs都是kv形式的数据,只不过logs携带了时间戳。

span中除了携带调用相关的信息外还携带了span之间的关联数据。看references字段知道span之间有父子关系(child_of)和顺序执行(follow_from)的关系,span按照相互之间关系组织起来就是trace。trace通常表现为由span组成的有向无环图。下图展示了trace和span之间的关系。

jaeger client使用

demo如下。
首先初始化全局的tracer对象。

func JaegerInit() (opentracing.Tracer, io.Closer) {cfg := &config.Configuration{ServiceName: "MY_PROJECT_NAME",Sampler: &config.SamplerConfig{Type:  "const",Param: 1,},Reporter: &config.ReporterConfig{LogSpans:           true,LocalAgentHostPort: "127.0.0.1:6831",},Tags: []opentracing.Tag{},}tracer, closer, err := cfg.NewTracer()if err != nil {panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))}// 这里顺便将 tracer 放入全局范围,opentracing 其他 api 的内部// 实现会使用该全局的 traceropentracing.SetGlobalTracer(tracer)return tracer, closer
}

开始记录trace数据。

func main() {// "main" 是上面提到的operationName。通常是根据业务自定义名称,// 这里 StartSpan 没有传递任何的 opentracing.StartSpanOption 参数,// 所以得到的 span 是 root span。span := tracer.StartSpan("start")defer span.Finish()             // 将 span 存放到 context 中,其他函数可以从这个 context 中提取出// span 的拓扑关系ctx := opentracing.ContextWithSpan(context.Background(), span)helloStr := methodA(ctx, helloTo)methodB(ctx, helloStr)
}func methodA(ctx context.Context, helloTo string) string {// 从 context 中提取出span,如果 context 中没有span,// 则这里得到的 span 将是 root span。所以如果 span 在链路的前进过程中忘记// 传递,将会导致断链。span, _ := opentracing.StartSpanFromContext(ctx, "methodA")defer span.Finish()return "Hello! " + helloTo
}func methodB(ctx context.Context, helloStr string) {span, _ := opentracing.StartSpanFromContext(ctx, "methodB")defer span.Finish()
}

上面演示的是大多数情况下的场景,如果是调用的第一环就创建rootspan,否则可以从ctx中拿到相关信息并创建child span。ctx中传递数据其实本质是通过携带spanContext的数据结构实现的。spanContext的结构如下。

// SpanContext represents propagated span identity and state
type SpanContext struct {// traceID represents globally unique ID of the trace.// Usually generated as a random number.traceID TraceID// spanID represents span ID that must be unique within its trace,// but does not have to be globally unique.spanID SpanID// parentID refers to the ID of the parent span.// Should be 0 if the current span is a root span.parentID SpanID// Distributed Context baggage. The is a snapshot in time.baggage map[string]string// debugID can be set to some correlation ID when the context is being// extracted from a TextMap carrier.//// See JaegerDebugHeader in constants.godebugID string// samplingState is shared across all spanssamplingState *samplingState// remote indicates that span context represents a remote parentremote bool
}

但是很多情况下调用链路中不一定全是rpc请求,比如中间可能会经历http调用或者kafka等消息队列。这些情况在jaeger中是通过"uber-trace-id"的key来传递信息的,其value为trace-id:span-id:parent-span-id:sample的字符串,该信息会设置在http的header或者kafka的message中。这种情况下的demo如下。

func main() {clientContext, _ := opentracing.GlobalTracer().Extract(opentracing.TextMap, opentracing.TextMapCarrier(map[string]string{"uber-trace-id": traceId}))span := tracer.StartSpan("start",opentracing.ChildOf(clientContext))defer span.Finish()             ctx := opentracing.ContextWithSpan(context.Background(), span)helloStr := methodA(ctx, helloTo)methodB(ctx, helloStr)
}

【微服务】链路追踪 jaeger相关推荐

  1. 微服务链路追踪-SkyWalking

    微服务链路追踪-SkyWalking SkyWalking官网地址:https://skywalking.apache.org/ SkyWalking官方文档:https://skywalking.a ...

  2. SkyWalking 微服务链路追踪

    目录 8. SkyWalking 微服务链路追踪 8.1 介绍 SkyWalking 8.2 Skywalking---服务搭建 8.3 SkyWalking---接入服务 8.3.1 windows ...

  3. 微服务链路追踪SkyWalking

    微服务链路追踪SkyWalking 链路追踪介绍 skywalking是什么 SkyWalking环境搭建部署 SkyWalking跨多个微服务跟踪 SkyWalking UI介绍 SkyWalkin ...

  4. 微服务.链路追踪概述和方案 (Cat Zipkin Skywaking,Sluth等组件对比选型)

    概述 为什么追踪链路 1. 单体应用 过渡 到微服务 2. 微服务 必须导致 调用熵增加 3. 单体应用中两个问题显现出来:根据日志查询问题:调用链路和调用的性能. 4. 日志问题在以后的日志方案中研 ...

  5. 阿里P7架构师详解微服务链路追踪原理

    背景介绍 在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时,很难从错综复杂的服务调用网络中找到问题根源,从而 ...

  6. skywalking原理_微服务链路追踪原理

    作者:平也 来源:关爱程序员社区 背景介绍 在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时,很难从错综复杂 ...

  7. SpringCloud Sleuth + zipkin 实现微服务链路追踪功能

    一.微服务架构下的问题 在大型的微服务架构系统中,存在很多不同的微服务应用,不同的微服务有依赖着其他微服务,以及不同微服务有可能由不同的团队维护.那么在这种复杂的系统架构中,将会存在一些问题,比如: ...

  8. 微服务链路追踪之zipkin搭建

    前言 微服务治理方案中,链路追踪是必修课,SpringCloud的组件其实使用很简单,生产环境中真正令人头疼的往往是软件维护,接口在微服务间的调用究竟哪个环节出现了问题,哪个环节耗时较长,这都是项目上 ...

  9. 微服务链路追踪SkyWalking第一课 SkyWalking简介

    开篇词:从剖析 SkyWalking 源码到吃透 APM 核心知识 你好,我是你的 SkyWalking 老师徐郡明,网名吴小胖,你也可以叫我胖哥.进入互联网行业工作多年,主要从事基础组件开发相关的工 ...

  10. 全网最全的微服务链路追踪实践-SkyWalking(看这一篇就够了)

    链路追踪介绍 对于一个大型的几十个.几百个微服务构成的微服务架构系统,通常会遇到下面一些问题,比如: 1. 如何串联整个调用链路,快速定位问题? 2. 如何缕清各个微服务之间的依赖关系? 3. 如何进 ...

最新文章

  1. 网络地址和广播地址的作用
  2. com.android.tools.build:gradle:2.0.0-alpha3 build errors
  3. Android应用开发--MP3音乐播放器代码实现(二)
  4. java中Logger.getLogger(Test.class)
  5. TGE学习笔记07 - 脚本控制动画
  6. Twitter Storm 序列化
  7. 蚂蚁金服自研分布式关系数据库OceanBase上线阿里云
  8. HTML基础概念——head头部,及标签(文本、图像类型)
  9. 移动端点击保存图片_财经理财新闻资讯类网站织梦模板(带手机端)
  10. 一次性输血器行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  11. 经典网页设计:20个与众不同的国外 HTML5 网站
  12. 计算机控制系统中采样速率的选择
  13. Inpaint图片去水印工具
  14. 苹果7信号天线内部位置_苹果手机的天线在什么位置
  15. Python OpenCV 图片滑块验证码自动识别方案分析与自动化识别方案实现 图片相似度对比 OpenCV如何找到图片中的正方形并进行标记?
  16. Python创意编程100例turtle篇题目串烧
  17. fast-reid中的sbs
  18. Java RGB转色温(CCT)
  19. Oracle 数据库一键安装,从未如此简单
  20. 爬虫(Spider)与反爬虫(Anti-Spider)

热门文章

  1. 3、哈哈哈-(2)hahaha1.py
  2. 如何成为一名出色SEO从业人员
  3. 3GPP TS 23501-g51 中英文对照 | 4.4.7 MSISDN-less MO SMS Service
  4. ChatGPT,背后的核心是什么?
  5. alitum designer 快速制作元器件封装
  6. 网站SEO优化之图片优化方法
  7. ikbc c87 Win键失灵/锁定
  8. Shell正则表达式详解(一)
  9. AutoML-第七章-AutoNet
  10. win7启动无法自动修复此计算机,win7系统启动修复_win7系统中启动修复无法自动修复此计算机情况的三种解决方法介绍_win7双系统启动修复...