关于全链路日志实现学习笔记

大家好,我叫大鸡腿,大家可以关注下我,会持续更新技术文章还有人生感悟,感谢~

在这里插入图片描述

文章目录

  • 学习原理的重要性
  • 前言
  • zipkin
  • sleuth
  • 别人公司自研全链路dubbo日志
  • 反思:我们公司框架下,如何自研
  • 异步场景如何记录到traceId
    • demo

学习原理的重要性

  在很多工作被框架实现之后,我们会越来越少了解里面的原理。
  原理这种东西,举个栗子形容一下,比如一辆汽车跑不起来了,一个经常修车的老师傅(没有拆过汽车)会跟你说,凭借我多年修车经验,可能是发动机坏了。然后给你换了发动机,结果还是起不来,配件一个一个换。这时一个工程师(了解汽车构造)过来看了一下,根据汽车各个部件的反应以及检测,最后跟你说是某个部件坏了,然后当着你的面把汽车拆出来,给你看确实是那个组件坏了,换完就跑起来了~

  废话了很多,就是了解原理可以让我们更加清晰的认识框架,更好的使用。

前言

  之前经常在技术群被肥朝哥问我们链路日志日志那么多怎么查看的,是怎么生成traceId的,今天我们来认真的学习一下。

  我看了下我们项目里面是没有配置traceId,但是日志里头却有,当时问了下我们架构师,也说不清,后面才发现是zipkin+sleuth来进行日志收集。

%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}

zipkin

  • zipkin官网

在架构里头

关于全链路日志实现学习笔记_第1张图片
我们可以看到需要中间层去设置traceId以及异步上报到zipkin统计里头

sleuth

  1. sleuth官网

关于全链路日志实现学习笔记_第2张图片
  注意一下,这里提供了一个很重要的思路:就是在客户端的时候使用上下文去储存traceId,在远程调用的时候,在header加参数,在服务提供者加到上下文进行缓存。

关于全链路日志实现学习笔记_第3张图片

别人公司自研全链路dubbo日志

  • Dubbo全链路追踪日志的实现

总结

  dubbo我本人不是经常用,大概思路是client和service端使用ThreadLocal去缓存traceId,在rpc上使用RpcContext 上下文传递。跟上面sleuth的原理差不多。

反思:我们公司框架下,如何自研

  如果自研的话,我们用的是Fegin,在远程调用的时候同样需要获取上下文~

  同样我也没有了解或者实践过只能贴一下别人的博客,之后再进行验证:Spring Cloud Feign添加自定义Header

异步场景如何记录到traceId

参考文章

  • 基于SLF4J MDC机制实现日志的链路追踪
  • mdc官网

主要看下官网的这一段:
在这里插入图片描述
除了使用ThreadLocal来缓存traceId之后可以用slfj的MDC来设置参数!

关于全链路日志实现学习笔记_第4张图片
在调用前进行获取,在run前设置进去。

demo

定义一个内部类

static class MyThreadPoolTaskExecutor extends ThreadPoolExecutor {

        public MyThreadPoolTaskExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }

        @Override
        public void execute(Runnable task) {
            Map context = MDC.getCopyOfContextMap();
            super.execute(() -> putMap(task, context));
        }

        private void putMap(Runnable task, Map context) {
            MDC.setContextMap(context);
            try {
                task.run();
            } finally {
                MDC.clear();
            }
        }
    }

测试demo

public static void main(String[] args) {
        MDC.put("traceId",String.valueOf(new Random().nextInt(100)));
        MyThreadPoolTaskExecutor executor=new MyThreadPoolTaskExecutor(5,10,1,TimeUnit.SECONDS,new BlockingArrayQueue<>());
        for(int i=0;i<5;i++){
            Thread thread=new Thread(() -> System.out.println(MDC.getCopyOfContextMap()));
            executor.execute(thread);
        }
    }

运行结果

{traceId=20}
{traceId=20}
{traceId=20}
{traceId=20}
{traceId=20}

解释

  MDC.put(“traceId”,String.valueOf(new Random().nextInt(100)));这一步要看各自框架如何实现的,如果像我们公司使用zipkin+sleuth来上报统计日志,估计就是这个X-B3-TraceId咯~。或者ThreadLocal版本也一样,拿到之后丢到各自线程里头的变量就完事了。

你可能感兴趣的:(学习,java,开发语言)