全链路追踪traceId,ThreadLocal与ExecutorService
关于全链路追踪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的更多相关文章
- 基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪
原文链接:基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪 一.日志系统 1.日志框架 在每个系统应用中,我们都会使用日志系统,主要是为了记录必要的信息和方便排 ...
- Node.js 应用全链路追踪技术——[全链路信息获取]
全链路追踪技术的两个核心要素分别是 全链路信息获取 和 全链路信息存储展示. Node.js 应用也不例外,这里将分成两篇文章进行介绍:第一篇介绍 Node.js 应用全链路信息获取, 第二篇介绍 N ...
- go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)
目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...
- skywalking与pinpoint全链路追踪方案对比
由于公司目前有200多微服务,微服务之间的调用关系错综复杂,调用关系人工维护基本不可能实现,需要调研一套全链路追踪方案,初步调研之后选取了skywalking和pinpoint进行对比; 选取skyw ...
- 【AWS】使用X-Ray做AWS云上全链路追踪监控系统
功能 AWS X-Ray 是一项服务,收集应用程序所请求的相关数据,并提供用于查看.筛选和获取数据洞察力的工具,以确定问题和发现优化的机会. 对于任何被跟踪的对您应用程序的请求,不仅可以查看请求和响应 ...
- 全链路追踪体验—最简陋TraceId的生成
对于后端开发来说,排查问题是常有的事情.而排查问题时最常用的就是看日志,看一次调用中经过了哪些系统,是那个系统出问题了.这就需要业务日志中关联调用链的TraceId信息,从而在应用出现问题时,能够通过 ...
- 全链路跟踪TraceId
数据库主键:标示唯一一条数据,譬如唯一商品,唯一订单 全局事务ID:实现分布式事务一致性的必备良药 请求ID:requestId,seesionId,标示一个请求或者一次会话的生命周期 身份证ID:代 ...
- Spring Cloud全链路追踪实现(Sleuth+Zipkin+RabbitMQ+ES+Kibana)
简介 在微服务架构下存在多个服务之间的相互调用,当某个请求变慢或不可用时,我们如何快速定位服务故障点呢?链路追踪的实现就是为了解决这一问题,本文采用Sleuth+Zipkin+RabbitMQ+ES+ ...
- Spring Cloud 全链路追踪实现
简介 在微服务架构下存在多个服务之间的相互调用,当某个请求变慢或不可用时,我们如何快速定位服务故障点呢?链路追踪的实现就是为了解决这一问题,本文采用Sleuth+Zipkin+RabbitMQ+ES+ ...
随机推荐
- Java集合之HashSet/TreeSet原理
Set集合 1.HashSet 只去重复, 没有顺序 HashSet的add方法会调用hashCode和equals, 所以存储在HashSet中的对象需要重写这两个方法. 2.TreeSet ...
- <mvc:annotation-driven/>的作用
<mvc:annotation-driven>的作用是: 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapt ...
- 字符串经过base64编码后的长度与原字符串的长度是什么关系呀?
beforeEncode为Encode之前的字符串 那么Encode后的字符串长度为: 1.如果beforeEncode.length()是3的整数倍,那么长度为 (beforeEncode.len ...
- SpannableString的基本用法
原文地址:http://www.cnblogs.com/kross/p/3645594.html 以前一直好奇QQ的输入框里面是如何出现表情的,今天看了下这个,心中发出“原来是这样啊”的感叹. 通常情 ...
- ACM数论之旅5---数论四大定理(你怕不怕(☆゚∀゚)老实告诉我)
(本篇无证明,想要证明的去找度娘)o(*≧▽≦)ツ ----------数论四大定理--------- 数论四大定理: 1.威尔逊定理 2.欧拉定理 3.孙子定理(中国剩余定理) 4.费马小定理 (提 ...
- BibTex相关
标签(空格分隔): 杂七杂八的问题 又到了写论文的高峰期(?)在BibTeX中添加参考文献时,发现选项很多,对一些称呼还是一脸懵逼..阿一古,也许是最后一次写论文了,还弄清楚的还是清楚一下吧~ [转自 ...
- C++模板学习笔记
一个有趣的东西:实现一个函数print, 输入一个数组, 输出数组的各个维度长度. eg. ], b[][], c[][][]; print(a); //(2, 4) print(b); //(3, ...
- Fork/Join框架实现原理
ForkJoinPool由ForkJoinTask数组和ForkJoinWorkerThread数组组成,ForkJoinTask数组负责存放程序提交给ForkJoinPool的任务,而ForkJoi ...
- nginx之编译安装
一.认识nginx 常用的web服务有Apache.IIS(windows系统).Lighttpd.Tomcat.Nginx等.Nginx是一个开源的,支持高性能.高并发的www服务和代理服务软件.它 ...
- response.sendRedirect()和request.getRequestDispatcher().forward(request,response)的区别
转发方式:request.getRequestDispatcher().forward(); 重定向方式:response.sendRedirect(); 下面是HttpServletRespons ...