Jaeger OpenTracing 体验

Jaeger OpenTracing

Jaeger项目地址
OpenTracing-Golang项目地址
这个Jaeger是Uber的分布式追踪系统,可以说是调用链追踪吧,这些调用链追踪系统都是参照Dapper。这里有一个中文版翻译,可以看看:
Dapper 翻译
按照我的理解,应该就是给一个调用链一个全局ID,无论是走RPC调用还是直接Restful HTTP调用,都需要带着这个ID,这样就可以形成一个链,根据这个ID就可以把Span的信息全部串起来了。

Jaeger架构图和组件

架构图

这里盗张图,Jaeger官网:
Jaeger架构
刚开始看到这张图我也是懵逼的,怎么会有这么多东西,这几个怎么串起来的,跟OpenTracing又是啥关系,怎么把Data Store换成ES或者kafka。我也是慢慢看文档,然后试出来的,后面的会给一个具体流程,希望有帮助。
下面看下各个组件

组件1 : Instrumentation + OpenTracing API

这两个是连在一块儿的,这两个东西都是插在我们业务代码里面的,就是要在我们的代码里面加入OpenTracing的代码。OpenTracing提供了很多语言的API,详细的可以看看上面的GitHub。对于Golang来说,主要的就是下面几个API:

opentracing.SetGlobalTracer()  //设置全局的tracer
opentracing.StartSpan() //开始一个span
opentracing.GlobalTracer().Inject() //把span信息注入到http请求里面
opentracing.GlobalTracer().Extract()  //从http请求里面解析出上一个服务的span信息

可以看到上面的SetGlobalTracer是可以设置成其他的tracer的,比如zipkin其他的,如果需要改动tracer的话,就只需要改这个参数即可,不需要改动其他插入的代码。

组件2 : Jaeger-client

Jaeger的客户端就相当于上面的tracer,在代码里面SetGlobalTracer的时候,参数传的就是Jaeger-client New出来的一个实例。既然是客户端,那么服务端是什么呢?服务端是Jaeger-agent。

组件3 : Jaeger-agent

这个是Jaeger的服务端,客户端会把Span的信息通过Jaeger.Thrift UDP传给Jaeger-agent,再由Jaeger-agent把这些span的信息传给Jaeger-collector。

为啥不直接把信息传到collector?从上面的图我猜测,collector应该是对agent有采样率的限制,在代码里面可以看到相关的设置。

组件4 : Jaeger-collector

负责把Jaeger-agent传过来的数据写入队列,并且保存到设定的存储介质里面[内存,ES,kafka…]

组件5 : Jaeger-query

这个是负责从存储介质里面读取调用链信息的,并且这个query自带UI,可以在UI里面看到相关的调用链。

搭建Demo流程[ES]

  1. 由于现在官网上面只支持ES5 和 ES6,所以我们可能不能使用最新的ES7,所以我们下载ES6:
    ES6
  2. 下载Jaeger相关组件二进制文件:
    Jaeger二进制文件
  3. 安装ES6,这个应该解包就能使用。
  4. 先启动ES,最好先启动ES,因为启动collector需要ES。
  5. 清除ES里面的相关index 清除index脚本
  6. 设置collector的环境变量,并且启动collector。
  7. 启动agent。
  8. 启动query。
#!/bin/bash
wget es.tar.gz
tar -xvzf es.tar.gz
wget jaeger.tar.gz
tar -xvzf jaeger.tar.gz
cd es/bin && ./elasticsearch
cd jaeger/bin
export SPAN_STORAGE_TYPE=elasticsearch
./jaeger-collector --es.server-urls=http://192.168.26.83:9200
./jaeger-agent --reporter.tchannel.host-port=192.168.26.83:14267
./jaeger-query --es.server-urls http://192.168.26.83:9200

上面的export是必须的,千万别忘了。第五点也是重点!!!
上面的export是必须的,千万别忘了。第五点也是重点!!!
上面的export是必须的,千万别忘了。第五点也是重点!!!
如果不出意外的话,lsof -i的话可以看到类似于下面的这张图:
在这里插入图片描述
从上面可以看到:
① 黄色框里面的内容:agent和collector建立了连接,14267这个端口的作用在文档里面有说:

14267- - - TChannel - - -used by jaeger-agent to send spans in jaeger.thrift format
是agent发送span给collector的通道

② 蓝色框里面的内容:分别是query组件和collector组件跟ES建立的连接,collector负责往ES里面写,query负责从ES里面读。

③ 红色框是代码里面初始化Jaeger-client之后,client跟agent建立起的连接,6831这个接口在文档里面有说:

6831- - - UDP- - -accept jaeger.thrift over compact thrift protocol
是client发送信息给agent的通道,通过thrift协议

现在应该就通了:
client生成的span信息通过6831发送到agent,agent再根据采样率来筛选记录,再通过14267传给collector,collector再通过9200往ES里面写,query通过9200从ES里面读并提供UI。

代码解析

最关键的就是Jaeger的初始化和OpenTracing的初始化:

 //这个是初始化jaeger-client的配置,包括采样率和报告方式
    cfg = jaegercfg.Configuration {
        Sampler : &jaegercfg.SamplerConfig {
            Type : "const",
            Param : 1,
        },  
        Reporter : &jaegercfg.ReporterConfig {
            LogSpans : true,
        },  
    }   
    
// 这个是创建jaeger-client,现在我们就可以得到一个jaeger tracer了
    tracer, closer, err := cfg.New(
        "elasticSearch-Jaeger",
        jaegercfg.Logger(jLogger),
        jaegercfg.Metrics(jMetricsFactory),
    )
    
//把OpenTracing的tracer设置成jaeger
    opentracing.SetGlobalTracer(tracer)
    
// 开始一个Span
    sp := opentracing.StartSpan("get_function")
    
// 创建子Span
    sp := opentracing.StartSpan(
        "one_function",
        opentracing.ChildOf(parentSpan.Context()))
        
// 结束span记录
	sp.Finish()
	
// 追加span 日志
sp.LogFields(
        openlog.String("Function_Name", logString),
        openlog.Int("Wating millis", 1000))

// 远程调用之前需要往请求里面注入当前的span信息:
    opentracing.GlobalTracer().Inject(
        sp.Context(),
        opentracing.HTTPHeaders,
        opentracing.HTTPHeadersCarrier(httpReq.Header))

// 远程调用响应时需要解析调用的span:
    wireContext, err := opentracing.GlobalTracer().Extract(
        opentracing.HTTPHeaders,
        opentracing.HTTPHeadersCarrier(r.Header))
    sp = opentracing.StartSpan(
        "second_service_function",
        ext.RPCServerOption(wireContext))

效果图

我们使用PostMan发送请求之后,可以在Jaeger-UI里面看到相关的调用链:
在这里插入图片描述
跟代码里面的sleep的时间是对应的上的,并且层级关系也很清楚。

如果你也启动了Kibana的话,那么在Kibana的页面也可以看到Span的相关信息:
在这里插入图片描述

代码

GitHub

最后

这个只是Demo,并且采样率设置的是每一条记录都需要收集,具体的参数还需要查阅文档或者代码,这边博客的目的在于了解并且开始熟悉OpenTracing,之前我对于这个OpenTracing的概念是模糊的,而且加上了Jaeger之后我更懵逼了, 通过一个星期的自学,我自己走了一遍流程,发现还是可以按照文档做出来一个Demo的,还是算比较欣慰吧,希望能帮助到大家。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
当您在Spring Boot应用程序中集成Jaeger时,您需要进行以下步骤: 1. 添加依赖:在您的Spring Boot项目的`pom.xml`文件中添加Jaeger客户端库的依赖项。例如: ```xml <dependency> <groupId>io.jaegertracing</groupId> <artifactId>jaeger-client</artifactId> <version>1.6.0</version> </dependency> ``` 2. 配置Jaeger:在您的应用程序的配置文件(如`application.properties`或`application.yml`)中添加Jaeger的配置。例如: ```yaml # Jaeger配置 jaeger: service-name: your-service-name udp-sender: host: localhost port: 6831 ``` 这里,您需要指定`service-name`作为您的应用程序的名称,并配置Jaeger的发送器(可以是UDP、HTTP等)的主机和端口。 3. 创建Jaeger Tracer Bean:在您的Spring Boot应用程序的配置类中创建一个Jaeger Tracer Bean。例如: ```java import io.jaegertracing.Configuration; import io.jaegertracing.internal.samplers.ConstSampler; import io.opentracing.Tracer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JaegerConfig { @Bean public Tracer jaegerTracer() { Configuration.SamplerConfiguration samplerConfig = Configuration.SamplerConfiguration.fromEnv() .withType(ConstSampler.TYPE) .withParam(1); Configuration.ReporterConfiguration reporterConfig = Configuration.ReporterConfiguration.fromEnv() .withLogSpans(true); Configuration config = new Configuration("your-service-name") .withSampler(samplerConfig) .withReporter(reporterConfig); return config.getTracer(); } } ``` 在上面的代码中,我们创建了一个`jaegerTracer()`方法,该方法使用了Jaeger的配置和参数,并返回一个Jaeger Tracer实例。 4. 使用Jaeger Tracer:在您的应用程序中使用注入的Jaeger Tracer实例进行跟踪。例如,在您的控制器类中: ```java import io.opentracing.Span; import io.opentracing.Tracer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class MyController { @Autowired private Tracer tracer; @GetMapping("/hello") public String hello() { Span span = tracer.buildSpan("helloSpan").start(); // 执行您的业务逻辑 span.finish(); return "Hello, World!"; } } ``` 在上面的例子中,我们使用了注入的`tracer`实例创建了一个Span,用于跟踪`hello()`方法的执行。您可以根据需要在其他地方创建更多的Span。 5. 运行Jaeger Agent:在集成Jaeger之前,请确保Jaeger Agent正在运行并监听所配置的主机和端口。Jaeger Agent负责接收来自应用程序的跟踪数据并将其发送到Jaeger Collector。 这样,您就完成了Spring Boot应用程序与Jaeger的集成。 请注意,这只是一个简单的示例,您可以根据您的需求进行更复杂的集成。更多关于Jaeger的配置和使用方法,请参考Jaeger的官方文档。 希望这个示例对您有所帮助!如有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值