分布式链路追踪如何跨线程
背景
我们希望实现全链路信息,但是代码中一般都会异步的线程处理。

解决思路
我们可以对以前的 Runable 和 Callable 进行增强。
可以使用 ali 已经存在的实现方式。
TransmittableThreadLocal (TTL) 解决异步执行时上下文传递的问题
核心的实现思路如下:
1)异步执行前,把当前线程的 MDC 信息放入执行对象中。
2)异步执行时,把执行对象中的信息放入 MDC 等信息。
3) 异步执行后,清空执行对象。
问题
Runable 和 Callable 只是接口,没有额外信息,所以需要进行增强。
实现方式
接口定义
package com.github.houbb.heaven.support.concurrent.context;import java.util.Map;/*** 跨线程处理类** @since 0.3.0*/
public interface CrossThreadProcessor {/*** 初始化上下文* @param contextMap 上下文*/void initContext(Map<String, Object> contextMap);/*** 执行之前* @param contextMap 上下文*/void beforeExecute(Map<String, Object> contextMap);/*** 执行之后* @param contextMap 上下文*/void afterExecute(Map<String, Object> contextMap);}
对可执行接口进行增强
package com.github.houbb.heaven.support.concurrent.context;import com.github.houbb.heaven.util.lang.SpiUtil;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;/*** 跨线程处理** 作用:用来跨线程处理传递信息,比如 async,线程池等。** 比如在 aop 中,直接处理。** <pre>* Object[] args = point.args();* Object arg0 = args[0];** // 直接转换为当前的对象* if(arg0 instanceOf Runnable) {* args[0] = new CrossThreadWrapper((Runnable)arg0);* } else if(arg0 instanceOf Callable) {* args[0] = new CrossThreadWrapper((Callable)arg0);* }** // 继续处理* </pre>* @param <T> 泛型* @since 0.3.0*/
public class CrossThreadWrapper<T> implements Runnable, Callable<T> {private Runnable runnable;private Callable<T> callable;/*** 通过 spi 获取所有的实现类*/private static List<CrossThreadProcessor> processorList = new ArrayList<>();/*** 上下文*/private final Map<String, Object> context = new HashMap<>();static {processorList = SpiUtil.getClassImplList(CrossThreadProcessor.class);}public CrossThreadWrapper(Runnable runnable) {// 任务执行之前this.initContext();this.runnable = runnable;}public CrossThreadWrapper(Callable<T> callable) {this.initContext();this.callable = callable;}@Overridepublic void run() {try {beforeExecute();this.runnable.run();} finally {afterExecute();}}@Overridepublic T call() throws Exception {try {beforeExecute();return this.callable.call();} finally {afterExecute();}}/*** 初始化上下文*/protected void initContext() {for(CrossThreadProcessor processor : processorList) {processor.initContext(context);}}/*** 执行前*/protected void beforeExecute() {for(CrossThreadProcessor processor : processorList) {processor.beforeExecute(context);}}/*** 执行之后*/protected void afterExecute() {for(CrossThreadProcessor processor : processorList) {processor.afterExecute(context);}}}
用法
实现接口
我们只需要实现 CrossThreadProcessor 接口。
然后 spi 中配置,服务会自动发现。
aop
可以在 spring aop 中,对以前的方法执行进行增强。
相关文章:
分布式链路追踪如何跨线程
背景 我们希望实现全链路信息,但是代码中一般都会异步的线程处理。 解决思路 我们可以对以前的 Runable 和 Callable 进行增强。 可以使用 ali 已经存在的实现方式。 TransmittableThreadLocal (TTL) 解决异步执行时上下文传递的问题 核心的实现思路如下&#…...
怎样在线修剪音频文件了?【免费,无须注册】
怎样在线修剪音频文件了? 推荐一个免费网址,且不用任何注册,直接可以使用 https://mp3cut.net/cn/ 上传音频文件, 拖动前后滚动条,对音频文件进行修剪。 修剪完成,可以保存如下格式 enjoy!! 作者简介…...
iMeta框架使用方法
📢📢📢📣📣📣 哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝 一位上进心十足的【Java ToB端大厂…...
视频编辑软件 Premiere Pro 2024 macv24.0中文版 (pr2024)
Premiere Pro 2024 mac编辑任何现代格式的素材,从8K到虚拟现实。广泛的原生文件支持和简单的代理工作流程可以轻松使用您的媒体,即使在移动工作站上也是如此。提供针对任何屏幕或平台优化的内容比以往任何时候都快。 Premiere Pro 2024 Mac版软件介绍 视…...
C/C++:双向队列的实现
/** * * Althor:Hacker Hao * Create:2023.10.11 * */#include <bits/stdc.h> using namespace std; #define MAXSIZE 200 typedef struct Deque {int front; //头int rear; //尾int num; //队列中的元素数量int arr[MAXSIZE]; //队列中存储的数字 };Deque…...
MySQL逻辑架构
文章目录 逻辑架构剖析1. 连接层2. 服务层3. 引擎层4. 存储层 SQL执行流程1. MySQL中的 SQL执行流程(理论)2. MySQL8中的 SQL 执行流程(实践)确认profiling 是否开启多次执行相同SQL查询查看profiles查看profile 3. SQL语法顺序 数…...
python爬虫练手项目之获取某地企业名录
因为很多网站都增加了登录验证,所以需要添加一段利用cookies跳过登陆验证码的操作 import pandas as pd import requests from lxml import etree # 通过Chrome浏览器F12来获取cookies,agent,headers cookies {ssxmod_itna2:eqfx0DgQGQ0QGDC…...
Python —— 接口自动化(1)
1、接口测试的基础概述 1、接口测试的方式 1、主流的工具类型 - jmeter,postman,apifox,fastapi,apipost.... 2、公开的自动化平台 - metersphere,yapi.... 3、公司内部自研平台 - 4、全面使用代码自己去完成框架搭建,项目实战.... 不论是平台还是工具࿰…...
【MySQL】关于MySQL升级到8.0版本的实践方案
关于MySQL升级到8.0版本的实践方案 关于数据库版本升级,一直都是热议话题,对于升级的缘由各家也有所不同,有业务驱动的,有DBA自发驱动的,有规划导向也有方向指引的……抛开各种原因,当升级这个决定落下来的时候,对于DBA手头的几百几千套数据库来说,就好比是一场动物大…...
【Python-Django】基于TF-IDF算法的医疗推荐系统复现过程
复现步骤 step1: 修改原templates路径,删除,将setting.py中的路径置空 step2: 注册app python manage.py startapp [app名称]在app目录下创建static和templates目录 step3: 将项目中的资源文化进行拷贝 step4&#…...
车辆车型识别系统python+TensorFlow+Django网页界面+算法模型
一、介绍 车辆车型识别系统。本系统使用Python作为主要开发编程语言,通过TensorFlow搭建算法模型网络对收集到的多种车辆车型图片数据集进行训练,最后得到一个识别精度较高的模型文件。并基于该模型搭建Django框架的WEB网页端可视化操作界面。实现用户上…...
小程序如何设置各种时间参数
在小程序管理员后台->基本设置处,可以设置各种时间。例如待支付提醒时间、待支付取消时间、自动发货时间、自动收货时间、自动评价时间等等。下面具体解释一下各个时间的意思。 1. 待支付提醒时间:在用户下单后,如果一段时间内没有完成支付…...
CSS变量 var()的用法
写在前面 这里介绍一下开发中常用的css变量var(),它可以实现样式的动态设置,使用方法主要分为全局使用和局部使用两种。 如何定义CSS变量var() 在CSS文件中,变量需要使用 – 作为前缀来定义,后面跟上变量名和值,如&a…...
设计模式——21. 中介者模式
1. 说明 中介者模式(Mediator Pattern)是一种行为设计模式,它允许对象之间通过一个中介者对象进行通信,而不是直接相互引用。这种模式有助于减少对象之间的直接关联,从而提高系统的可维护性和松耦合性。中介者模式将对象之间的交互集中在一个中介者对象中,该对象负责协调…...
fastjson 1.2.47 远程命令执行漏洞
fastjson 1.2.47 远程命令执行漏洞 文章目录 fastjson 1.2.47 远程命令执行漏洞1 在线漏洞解读:2 环境搭建3 影响版本:4 漏洞复现4.1 访问页面4.2 bp抓包,修改参数 5 使用插件检测漏洞【FastjsonScan】5.1使用説明5.2 使用方法5.2.1 右键菜单中ÿ…...
【k8s 开发排错】k8s组件开发排错之pprof
参考 Kubernetes组件问题排查的一些方法 - 知乎 go 程序性能调优 pprof 的使用 (一) - 润新知 Go进阶系列 之 性能分析神器pprof__好吗_好的的博客-CSDN博客 k8s各组件端口_k8s10259端口-CSDN博客 Go调试神器pprof使用教程【实战分享】_NPE~的博客-C…...
记录一次典型oom的处理过程
背景 有同学反馈收到应用RT的报警,其中的流量都来自于网关集群中的一台机器。因为负责网关,就上去看了下并进行排查。整体是一个比较明显的oom,这里只是记录下排查过程,老司机可以略过了。 初步现象 常规步骤,使用t…...
centos离线安装telnet、traceroute工具
安装包下载地址 安装包下载地址在这里 直接输入包名,筛选系统,根据自己系统版本确定该下哪个包 centos离线安装telnet 准备三个安装包 xinetd-2.3.15-14.el7.x86_64.rpmtelnet-server-0.17-65.el7_8.x86_64.rpmtelnet-0.17-65.el7_8.x86_64.rpm 三个…...
【java学习—七】对象的实例化过程(33)
文章目录 1. 简单类对象的实例化过程2. 子类对象的实例化过程 1. 简单类对象的实例化过程 2. 子类对象的实例化过程...
P4451 [国家集训队] 整数的lqp拆分
传送门:洛谷 解题思路: 考虑设 f ( i ) f(i) f(i)为和为 i i i的拆分权值和,那么我们可以得到一个递推关系式 f ( i ) ∑ i 1 n f ( n − i ) ∗ f i b ( i ) f(i)\sum_{i1}^nf(n-i)*fib(i) f(i)i1∑nf(n−i)∗fib(i)这个表达式的含义就是枚举一个数的值,由于分配率,我们…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
