写点什么

微服务链路追踪之 Jaeger

用户头像
雪雷
关注
发布于: 2020 年 08 月 21 日
微服务链路追踪之Jaeger

一 Jaeger概述



在微服务为我们提供了模块分,低耦合的高效开发和DevOPS中,具体业务中当一个请求中,请求了多个服务单元,如果请求出现了错误或异常,很难去定位是哪个服务出了问题,这时就需要链路追踪。可能你会想在业务系统中请求中埋点,或写日志,但是这种都需要在业务代码中来写,而且耦合在代码中,不具备微服务的扩张性后后期的易维护行。



1.1 Jaeger概念



受Dapper和OpenZipkin启发的Jaeger是由Uber Technologies作为开源发布的分布式跟踪系统。它用于监视和诊断基于微服务的分布式系统,包括:



  • 分布式上下文传播

  • 分布式交易监控

  • 根本原因分析

  • 服务依赖性分析性能/延迟优化



1.2 特性



1.2.1 高扩展性



Jaeger后端的设计没有单点故障,可以根据业务需求进行扩展。例如,Uber上任何给定的Jaeger安装通常每天要处理数十亿个跨度。



1.2.2 原生支持OpenTracing



Jaeger后端,Web UI和工具库已完全设计为支持OpenTracing标准。



  • 通过跨度引用将迹线表示为有向无环图(不仅是树)



  • 支持强类型的跨度标签和结构化日志通过行李



  • 支持通用的分布式上下文传播机制



1.2.3 多存储后端



Jaeger支持两个流行的开源NoSQL数据库作为跟踪存储后端:Cassandra 3.4+和Elasticsearch 5.x / 6.x / 7.x。正在进行使用其他数据库的社区实验,例如ScyllaDB,InfluxDB,Amazon DynamoDB。Jaeger还附带了一个简单的内存存储区,用于测试设置。



1.2.4 现代化的UI



Jaeger Web UI是使用流行的开源框架(如React)以Javascript实现的。v1.0中发布了几项性能改进,以允许UI有效处理大量数据,并显示具有成千上万个跨度的跟踪(例如,我们尝试了具有80,000个跨度的跟踪)。



1.2.5 云原生部署



Jaeger后端作为Docker映像的集合进行分发。这些二进制文件支持各种配置方法,包括命令行选项,环境变量和多种格式(yaml,toml等)的配置文件。Kubernetes模板和Helm图表有助于将其部署到Kubernetes集群。



1.2.6 可观察性



默认情况下,所有Jaeger后端组件都公开Prometheus指标(也支持其他指标后端)。使用结构化日志库zap将日志写到标准输出。



1.2.7 安全



Jaeger的第三方安全审核可在https://github.com/jaegertracing/security-audits中获得。有关Jaeger中可用安全机制的摘要,请参见问题#1718。



1.2.8 与Zipkin的向后兼容性



尽管我们建议使用OpenTracing API来对应用程序进行检测并绑定到Jaeger客户端库,以从其他地方无法获得的高级功能中受益,但是如果您的组织已经使用Zipkin库对检测进行了投资,则不必重写所有代码。Jaeger通过在HTTP上接受Zipkin格式(Thrift或JSON v1 / v2)的跨度来提供与Zipkin的向后兼容性。从Zipkin后端切换只是将流量从Zipkin库路由到Jaeger后端的问题。



二 快速入门



您的应用程序必须经过检测,然后才能将跟踪数据发送到Jaeger后端。查看“客户端库”部分,以获取有关如何使用OpenTracing API以及如何初始化和配置Jaeger跟踪器的信息。



2.1 简介



您的应用程序必须经过检测,然后才能将跟踪数据发送到Jaeger后端。查看“客户端库”部分,以获取有关如何使用OpenTracing API以及如何初始化和配置Jaeger跟踪器的信息。



2.2 All in One



多合一是用于快速本地测试的可执行文件,具有内存存储组件,可启动Jaeger UI,收集器,查询和代理。开始多合一的最简单方法是使用发布到DockerHub的预构建映像(单个命令行)。



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.14



Or run the jaeger-all-in-one(.exe) executable from the binary distribution archives:



jaeger-all-in-one --collector.zipkin.http-port=9411



You can then navigate to http://localhost:16686 to access the Jaeger UI.



容器需要暴露的端口



| Port | Protocol | Component | Function |

| :---- | :------- | :-------- | :----------------------------------------------------------- |

| 5775 | UDP | agent | accept zipkin.thrift over compact thrift protocol (deprecated, used by legacy clients only) |

| 6831 | UDP | agent | accept jaeger.thrift over compact thrift protocol |

| 6832 | UDP | agent | accept jaeger.thrift over binary thrift protocol |

| 5778 | HTTP | agent | serve configs |

| 16686 | HTTP | query | serve frontend |

| 14268 | HTTP | collector | accept jaeger.thrift directly from clients |

| 14250 | HTTP | collector | accept model.proto |

| 9411 | HTTP | collector | Zipkin compatible endpoint (optional) |



2.3 Kubernetes and OpenShift



  • Kubernetes templates: https://github.com/jaegertracing/jaeger-kubernetes

  • Kubernetes Operator: https://github.com/jaegertracing/jaeger-operator

  • OpenShift templates: https://github.com/jaegertracing/jaeger-openshift



2.4 示例APP:HotROD



HotROD(按需乘车)是一个演示应用程序,由几个微服务组成,并说明了OpenTracing API的用法。博客文章中提供了一个教程/演练:以OpenTracing API.的方式进行HotROD。它可以独立运行,但需要Jaeger后端才能查看跟踪。[Take OpenTracing for a HotROD ride](https://medium.com/@YuriShkuro/take-opentracing-for-a-hotrod-ride-f6e3141f7941)



2.4.1 特性



  • 通过数据驱动的依赖关系图发现整个系统的体系结构

  • 查看请求时间表和错误;了解应用程序的工作方式。

  • 查找延迟和缺乏并发的来源。

  • 高度上下文化的日志记录。

  • 使用行李传播来:

* 诊断请求间争用(排队)。

* 服务花费的属性时间

  • 将开源库与OpenTracing集成一起使用可免费获得与供应商无关的工具。



2.4.2 先决条件



  • 您需要在计算机上安装Go 1.11或更高版本才能从源代码运行

  • 需要运行的Jaeger后端才能查看跟踪



2.4.3 运行



2.4.3.1 源码



mkdir -p $GOPATH/src/github.com/jaegertracing
cd $GOPATH/src/github.com/jaegertracing
git clone git@github.com:jaegertracing/jaeger.git jaeger
cd jaeger
make install
go run ./examples/hotrod/main.go all



2.4.3.2 docker



docker run --rm -it \
--link jaeger \
-p8080-8083:8080-8083 \
-e JAEGER_AGENT_HOST="jaeger" \
jaegertracing/example-hotrod:1.14 \
all



2.4.3.3 二进制



Run example-hotrod(.exe) executable from the binary distribution archives:



$ example-hotrod all



Then navigate to http://localhost:8080.



2.5 从Zipkin迁移



收集器服务公开了Zipkin兼容的REST API / api / v1 / spans,该API接受Thrift和JSON。此外,还有/ api / v2 / spans用于JSON和Proto。默认情况下,它是禁用的。可以使用--collector.zipkin.http-port = 9411启用它



Zipkin Thrift IDL and Zipkin [Proto](https://github.com/jaegertracing/jaeger-idl/blob/master/proto/zipkin.proto) IDL files can be found in [jaegertracing/jaeger-idl](https://github.com/jaegertracing/jaeger-idl) repository. They’re compatible with [openzipkin/zipkin-api](https://github.com/openzipkin/zipkin-api) [Thrift](https://github.com/openzipkin/zipkin-api/blob/master/thrift/zipkinCore.thrift) and [Proto](https://github.com/openzipkin/zipkin-api/blob/master/zipkin.proto).



三 架构



3.1 术语



3.1.1 Span



Span表示Jaeger中的逻辑工作单元,具有操作名称,操作的开始时间和持续时间。跨度可以嵌套并排序以建立因果关系模型。





每个 Span 包含以下对象:



  • Operation name:操作名称 (也可以称作 Span name)。

  • Start timestamp:起始时间。

  • Finish timestamp:结束时间。

  • Span tag:一组键值对构成的 Span 标签集合。键值对中,键必须为 String,值可以是字符串、布尔或者数字类型。

  • Span log:一组 Span 的日志集合。每次 Log 操作包含一个键值对和一个时间戳。键值对中,键必须为 String,值可以是任意类型。

  • SpanContext: pan 上下文对象。每个 SpanContext 包含以下状态:

- 要实现任何一个 OpenTracing,都需要依赖一个独特的 Span 去跨进程边界传输当前调用链的状态(例如:Trace 和 Span 的 ID)。

- Baggage Items 是 Trace 的随行数据,是一个键值对集合,存在于 Trace 中,也需要跨进程边界传输。

  • References(Span 间关系):相关的零个或者多个 Span(Span 间通过 SpanContext 建立这种关系)。



3.1.2 Trace



跟踪是通过系统的数据/执行路径,可以看作跨度的有向无环图。



3.2 组件



Jaeger可以作为多合一二进制(其中所有Jaeger后端组件都在单个进程中运行)进行部署,也可以作为可扩展的分布式系统进行部署,如下所述。有两个主要的部署选项:



  • 收集器正在直接写入存储。





  • 收集器正在写信给Kafka作为初步缓冲。





本节详细介绍Jaeger的组成部分以及它们之间的关系。它由您的应用程序与之交互的顺序安排。



3.2.1 Jaeger client libraries



Jaeger客户端是OpenTracing API的特定于语言的实现。它们可用于手动或通过与OpenTracing集成的各种现有开源框架(例如Flask,Dropwizard,gRPC等)来检测应用程序以进行分布式跟踪。



检测服务在接收新请求时创建跨度,并将上下文信息(跟踪ID,跨度ID和行李)附加到传出请求。只有ID和行李随请求一起传播;不会传播构成跨度的所有其他信息,例如操作名称,日志等。取而代之的是,采样的跨度在后台异步传输到Jaeger Agents的过程外。



该仪器的开销很小,并且设计为始终在生产中启用。请注意,虽然生成了所有跟踪,但仅采样了一些。对跟踪进行采样将跟踪标记为进一步处理和存储。默认情况下,Jaeger客户端对0.1%的迹线进行采样(每1000个中的1个),并且能够从代理中检索采样策略。





3.2.2 Agent



Jaeger代理是一个网络守护程序,它侦听通过UDP发送的跨度,然后将其分批发送给收集器。它旨在作为基础结构组件部署到所有主机。该代理将收集器的路由和发现抽象到远离客户端的位置。



3.2.3 Collector



Jaeger收集器从Jaeger代理接收跟踪,并通过处理管道运行它们。当前,我们的管道会验证跟踪,为其建立索引,执行任何转换并最终存储它们。Jaeger的存储设备是可插拔组件,目前支持Cassandra,Elasticsearch和Kafka。



3.2.4 Query



查询是一项从存储中检索跟踪并托管UI来显示跟踪的服务。



3.2.5 Ingester



Ingester is a service that reads from Kafka topic and writes to another storage backend (Cassandra, Elasticsearch).



3.3 Sampling



Jaeger库实现了一致的前期(或基于头)的采样。例如,假设我们有一个简单的调用图,其中服务A调用服务B,服务B调用服务C:A-> B->C。当服务A收到不包含跟踪信息的请求时,Jaeger跟踪器将开始新的跟踪,为其分配一个随机跟踪ID,然后根据当前安装的采样策略做出采样决定。采样决策将与请求一起传播到B和C,因此这些服务将不会再次做出采样决策,而是会尊重顶级服务A做出的决策。这种方法保证了,如果对跟踪进行了采样,则所有其跨度将记录在后端。如果每个服务都做出自己的抽样决定,那么我们很少会在后端获得完整的跟踪。



3.3.1 客户端采样配置



使用配置对象实例化跟踪器时,可以通过sampler.type和sampler.param属性选择采样类型。Jaeger库支持以下采样器:



  • Constant (sampler.type=const) sampler always makes the same decision for all traces. It either samples all traces (sampler.param=1) or none of them (sampler.param=0).

  • Probabilistic (sampler.type=probabilistic) sampler makes a random sampling decision with the probability of sampling equal to the value of sampler.param property. For example, with sampler.param=0.1 approximately 1 in 10 traces will be sampled.

  • Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate limiter to ensure that traces are sampled with a certain constant rate. For example, when sampler.param=2.0 it will sample requests with the rate of 2 traces per second.

  • Remote (sampler.type=remote, which is also the default) sampler consults Jaeger agent for the appropriate sampling strategy to use in the current service. This allows controlling the sampling strategies in the services from a central configuration in Jaeger backend, or even dynamically (see [Adaptive Sampling](https://github.com/jaegertracing/jaeger/issues/365)).



3.3.2 适配示例



自适应采样器是一个组合了两个功能的复合采样器:



  • 它基于每个操作(即基于跨度操作名称)做出抽样决策。这在API服务中尤其有用,这些API服务的端点的流量可能非常不同,并且对整个服务使用单个概率采样器可能会使某些低QPS端点饿死(从不采样)。

  • 它支持最低的保证采样率,例如始终允许每秒最多N条迹线,然后以一定的概率对所有采样率进行采样(一切都是针对每个操作,而非针对每个服务)。



可以静态配置每个操作参数,也可以在远程采样器的帮助下从Jaeger后端定期提取每个操作参数。自适应采样器旨在与Jaeger后端即将推出的自适应采样功能一起使用。



3.3.3 集合示例配置



可以通过--sampling.strategies-file选项使用静态采样策略实例化收集器(如果使用Remote sampler配置,则将其传播到相应的服务)。此选项需要一个已定义采样策略的json文件路径。



{
"service_strategies": [
{
"service": "foo",
"type": "probabilistic",
"param": 0.8,
"operation_strategies": [
{
"operation": "op1",
"type": "probabilistic",
"param": 0.2
},
{
"operation": "op2",
"type": "probabilistic",
"param": 0.4
}
]
},
{
"service": "bar",
"type": "ratelimiting",
"param": 5
}
],
"default_strategy": {
"type": "probabilistic",
"param": 0.5
}
}




四 示例测试



访问:http://139.9.163.110:8080/









代码示例可参考一位go大佬的一个示例:https://github.com/xinliangnote/go-gin-api



参考链接



  • https://github.com/jaegertracing/jaeger

  • https://jaegertracing.io/docs/

  • https://github.com/jaegertracing/jaeger-client-python



发布于: 2020 年 08 月 21 日阅读数: 98
用户头像

雪雷

关注

stay hungry stay foolish 2019.08.16 加入

Devops,python,shell,云原生,云架构,kubernetes https://github.com/redhatxl

评论

发布
暂无评论
微服务链路追踪之Jaeger