关于全链路追踪traceId遇到线程池的问题,做过架构的估计都遇到过,现在以写个demo,总体思想就是获取父线程traceId,给子线程,子线程用完移除掉。

mac上的chrome时不时崩溃,写了一大半的博客没了,直接贴源码和注释吧

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class ThreadPoolTracing { private static final Logger logger = LoggerFactory.getLogger(ThreadPoolTracing.class);
public static ThreadLocal<String> threadLocalTraceId = new ThreadLocal<>(); static class Task implements Runnable { @Override
public void run() {
String traceId=threadLocalTraceId.get();
logger.info("traceId={}",traceId);
}
}
}
public class MyTest2 {

    private static final Logger loger = LoggerFactory.getLogger(MyTest2.class);
//线程池大小设置为一,保证是同一个线程run之前获取traceId,run后删除,便于测试
private static ExecutorService executorService = Executors.newFixedThreadPool(1); @Test
public void test1() { String traceId = UUID.randomUUID().toString().replace("-", "");
ThreadPoolTracing.threadLocalTraceId.set(traceId);
loger.info("父线程={};traceId={}",Thread.currentThread().getName(),traceId); Runnable runnable=new Runnable() {
@Override
public void run() {
//ThreadLocal 拿不到值;如果是InheritableThreadLocal,可以拿到值
String id0 = ThreadPoolTracing.threadLocalTraceId.get();
loger.info("子线程={},traceId={}",Thread.currentThread().getName(),id0);
}
};
executorService.execute(runnable);//结果为空
executorService.execute(new ThreadPoolTracing.Task());//结果为空 Runnable wrap= wrap( runnable);
executorService.execute(wrap);//可以获取traceId
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
traceId = UUID.randomUUID().toString().replace("-", "");
//traceId 重新复制
ThreadPoolTracing.threadLocalTraceId.set(traceId);
loger.info("父线程={};traceId={}",Thread.currentThread().getName(),traceId);
//线程池中的traceId跟着变更
wrap= wrap( runnable);
executorService.execute(wrap); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public Runnable wrap(Runnable task) {
//获取父线程中的Trace
String id0 = ThreadPoolTracing.threadLocalTraceId.get();
class CurrentTraceContextRunnable implements Runnable {
@Override
public void run() {
//traceId 给子线程
ThreadPoolTracing.threadLocalTraceId.set(id0);
task.run();
//子线程用完删除
ThreadPoolTracing.threadLocalTraceId.remove();
}
}
return new CurrentTraceContextRunnable(); } }

全链路追踪traceId,ThreadLocal与ExecutorService的更多相关文章

  1. 基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪

    原文链接:基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪 一.日志系统 1.日志框架 在每个系统应用中,我们都会使用日志系统,主要是为了记录必要的信息和方便排 ...

  2. Node.js 应用全链路追踪技术——[全链路信息获取]

    全链路追踪技术的两个核心要素分别是 全链路信息获取 和 全链路信息存储展示. Node.js 应用也不例外,这里将分成两篇文章进行介绍:第一篇介绍 Node.js 应用全链路信息获取, 第二篇介绍 N ...

  3. go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)

    目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...

  4. skywalking与pinpoint全链路追踪方案对比

    由于公司目前有200多微服务,微服务之间的调用关系错综复杂,调用关系人工维护基本不可能实现,需要调研一套全链路追踪方案,初步调研之后选取了skywalking和pinpoint进行对比; 选取skyw ...

  5. 【AWS】使用X-Ray做AWS云上全链路追踪监控系统

    功能 AWS X-Ray 是一项服务,收集应用程序所请求的相关数据,并提供用于查看.筛选和获取数据洞察力的工具,以确定问题和发现优化的机会. 对于任何被跟踪的对您应用程序的请求,不仅可以查看请求和响应 ...

  6. 全链路追踪体验—最简陋TraceId的生成

    对于后端开发来说,排查问题是常有的事情.而排查问题时最常用的就是看日志,看一次调用中经过了哪些系统,是那个系统出问题了.这就需要业务日志中关联调用链的TraceId信息,从而在应用出现问题时,能够通过 ...

  7. 全链路跟踪TraceId

    数据库主键:标示唯一一条数据,譬如唯一商品,唯一订单 全局事务ID:实现分布式事务一致性的必备良药 请求ID:requestId,seesionId,标示一个请求或者一次会话的生命周期 身份证ID:代 ...

  8. Spring Cloud全链路追踪实现(Sleuth+Zipkin+RabbitMQ+ES+Kibana)

    简介 在微服务架构下存在多个服务之间的相互调用,当某个请求变慢或不可用时,我们如何快速定位服务故障点呢?链路追踪的实现就是为了解决这一问题,本文采用Sleuth+Zipkin+RabbitMQ+ES+ ...

  9. Spring Cloud 全链路追踪实现

    简介 在微服务架构下存在多个服务之间的相互调用,当某个请求变慢或不可用时,我们如何快速定位服务故障点呢?链路追踪的实现就是为了解决这一问题,本文采用Sleuth+Zipkin+RabbitMQ+ES+ ...

随机推荐

  1. 项目总结之关于JQuery一些常用的函数

    最近做一个小的项目,用到了很多关于jquery函数,下面简单总结下自我感觉比较常用的一些函数. jquery函数--Hide函数用法 jquery中,hide函数用于实现层的消失,相反,show函数用 ...

  2. sprint1

    6.0----------------------------------------------------- sprint演示 1.坚持所有的sprint都结束于演示. 团队的成果得到认可,会感觉 ...

  3. debug阶段团队贡献分分配

    小组名称:飞天小女警 项目名称:礼物挑选小工具 小组成员:沈柏杉(组长).程媛媛.杨钰宁.谭力铭 debug阶段各组员的贡献分分配如下: 姓名 团队贡献分 程媛媛 5.8 沈柏杉 6.5 谭力铭 3. ...

  4. 用node研究axios前后端交互状态码规则

    研究状态码规则围绕我的脑袋有些时间了. 加上最近比较不忙,开始了这方面的研究. 后端用的是直接跑过的node框架,express.可以直接参考express官方网站:http://www.expres ...

  5. js异步上传图片

    <!DOCTYPE html><html xmlns = "http://www.w3.org/1999/xhtml" ><head><m ...

  6. PHP 常用函数总结(一)

    重点: 看函数的 ‘参数’ 和 ‘返回值’ 文档:http://www.w3school.com.cn/php/php_ref_array.asp http://www.w3school.com.cn ...

  7. 查看ROS最大并发连接数量

    命令行下输入以下 ip firewall connection tracking print interval 1 max-entries这个就是最大的并发连接数量 退出按Q 

  8. GCC 提供的原子操作

    gcc从4.1.2提供了__sync_*系列的built-in函数,用于提供加减和逻辑运算的原子操作. 其声明如下: type __sync_fetch_and_add (type *ptr, typ ...

  9. 解决 'findstr' 不是内部或外部命令,也不是可运行的程序或批处理文件 提示问题

    如果出现提示“出现'findstr' 不是内部或外部命令,也不是可运行的程序或批处理文件” 这是PATH环境变量的问题,将windows命令的目录添加到PATH中就over了.即:在path中追加:% ...

  10. 【uoj121】 NOI2013—向量内积

    http://uoj.ac/problem/121 (题目链接) 题意 给出${n}$个${d}$维向量,问是否有两个不同的向量的内积是${k}$的倍数. Solution 又卡了一上午常数,我弃了T ...