美文网首页
Jaeger服务端埋点分析

Jaeger服务端埋点分析

作者: huiwq1990 | 来源:发表于2019-10-24 13:34 被阅读0次

1 类介绍

1.1 TracingFilter介绍

配置

配置类io.opentracing.contrib.spring.web.starter.ServerTracingAutoConfiguration#tracingFilter引入Bean。
TraceFilter是普通的servlet filter,filter的引入有三种(我了解的)方式:
1)在web.xml里配置引入
2)在Filter类上面增加@WebFilter

  1. 通过bean注入
    特点是:前两种适合项目通过war包部署,最后适合springboot项目。

功能

从http协议头中获取span信息,如果SERVER_SPAN_CONTEXT为空,则根据头信息创建新的Span。

1.2 Interceptor

通过类io.opentracing.contrib.spring.web.starter.ServerTracingAutoConfiguration#tracingHandlerInterceptor引入。
它主要处理业务日志,拦截controller等(??)

2 源码解析

Tracer创建

Tracer主要是设置上报的服务器地址,采样率,项目名称等。
io.opentracing.contrib.java.spring.jaeger.starter.JaegerAutoConfiguration#tracer调用io.jaegertracing.internal.JaegerTracer.Builder新建Tracer对象。

    private ScopeManager scopeManager = new ThreadLocalScopeManager();
    private BaggageRestrictionManager baggageRestrictionManager = new DefaultBaggageRestrictionManager();
    private boolean expandExceptionLogs;
    private final JaegerObjectFactory objectFactory;
    private boolean useTraceId128Bit;
    private boolean manualShutdown;

    public Builder(String serviceName) {
      this(serviceName, new JaegerObjectFactory());
    }

这里有个点需要注意:ScopeManager的具体实现类是ThreadLocalScopeManager,稍后会解释。

注册Tracer对象

io.opentracing.contrib.spring.tracer.configuration.TracerRegisterAutoConfiguration#registerToGlobalTracer

可以通过GlobalTracer.get()方法获取对象。

Scope分析(非常重要)

Scope是站在CPU角度激活或者失效Span。ScopeManager管理Scope。
一个Scope里可以有多个span,但是只有一个激活的span。

    ThreadLocalScope(ThreadLocalScopeManager scopeManager, Span wrapped, boolean finishOnClose) {
        this.scopeManager = scopeManager;
        //绑定的span
        this.wrapped = wrapped;
        this.finishOnClose = finishOnClose;
        //暂存之前激活的span
        this.toRestore = scopeManager.tlsScope.get();
        // 设置当前线程绑定的scope
        scopeManager.tlsScope.set(this);
    }

    @Override
    public void close() {
        if (scopeManager.tlsScope.get() != this) {
            // This shouldn't happen if users call methods in the expected order. Bail out.
            return;
        }

        if (finishOnClose) {
            wrapped.finish();
        }
// 恢复之前的指向
        scopeManager.tlsScope.set(toRestore);
    }

在操作当span操作完成(span.finish)时,需要调用scope.close方法,触发关联新的激活span,否则调用链条会出错。

Span创建

            final Span span = tracer.buildSpan(httpRequest.getMethod())
                    .asChildOf(extractedContext)
                    .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER)
                    .start();

            httpRequest.setAttribute(SERVER_SPAN_CONTEXT, span.context());

            for (ServletFilterSpanDecorator spanDecorator: spanDecorators) {
                spanDecorator.onRequest(httpRequest, span);
            }

            try (Scope scope = tracer.activateSpan(span)) {
                chain.doFilter(servletRequest, servletResponse);
                if (!httpRequest.isAsyncStarted()) {
                    for (ServletFilterSpanDecorator spanDecorator : spanDecorators) {
                        spanDecorator.onResponse(httpRequest, httpResponse, span);
                    }
                }
            // catch all exceptions (e.g. RuntimeException, ServletException...)
            } catch (Throwable ex) {

span创建就是生成jaegerspan,并设置parent为从http头获取的span信息。

激活span

tracer.activateSpan是激活span,会触发创建一个ThreadLocalScope。
结果是可以通过tracer.scopeManager.activeSpan();获取span信息。

Span关闭

span.finish会触发span上报。

  private void finishWithDuration(long durationMicros) {
    synchronized (this) {
      if (finished) {
        log.warn("Span has already been finished; will not be reported again.");
        return;
      }
      finished = true;

      this.durationMicroseconds = durationMicros;
    }
    if (context.isSampled()) {
      tracer.reportSpan(this);
    }
  }

相关文章

  • Jaeger服务端埋点分析

    1 类介绍 1.1 TracingFilter介绍 配置 配置类io.opentracing.contrib.sp...

  • Jaeger链路跟踪埋点和上报代码分析

    https://www.jaegertracing.io/docs/1.17/architecture/ 知识点 ...

  • 埋点

    埋点分为客户端埋点和服务端埋点。客户端埋点通过restful api请求json数据写入kafka中,可以单条请求...

  • 埋点系列2-输出埋点需求文档

    上一章《埋点需求分析&设计埋点方案》已经说明了什么是埋点,埋点需求分析、数据指标、常见的埋点事件等基本概念。本周主...

  • iOS 列表cell曝光埋点

    什么是曝光埋点,简单的说就是展示在屏幕上了,然后往服务端上传一个埋点。那列表cell的曝光埋点就是cell进入屏幕...

  • vue中教你用decorator实现无痕埋点

    什么是埋点? 埋点分析,是网站分析的一种常用的数据采集方法。数据埋点分为初级、中级、高级三种方式。数据埋点是一种良...

  • 埋点系列3-埋点的框架设计及其准确性

    通过前两章《埋点需求分析&设计埋点方案》《输出埋点需求文档》,我们已经足够了解埋点,并且能够输出埋点文档了。但是想...

  • iOS埋点技术方案总结

    一、可视化埋点 可视化埋点的出现,是为解决代码埋点流程复杂、成本高、新开发的页面(H5、或者服务端下发的 json...

  • iOS学习笔记 无侵入的埋点方案

    埋点:用于了解用户使用App的行为 和 降低分析线上问题的难度。 目前常见的埋点方式:代码埋点、可视化埋点与无埋点...

  • Jaeger依赖分析

    一、依赖任务 1.1 k8s运行任务 1.2 查看任务状态 1.3 依赖关系结果 二、依赖任务实现 io.jaeg...

网友评论

      本文标题:Jaeger服务端埋点分析

      本文链接:https://www.haomeiwen.com/subject/ewirvctx.html