全链路日志追踪
背景
最近线上的日志全局追踪 traceId 不好使了,不同请求经常出现重复的 traceId,或者通过某个请求的 traceId 追踪搜索,检索出了与该请求完全不相干的日志。我领导叫我去排查解决这个问题,这里我把我排查的过程思路以及如何解决这个问题稍微记录下。
全链路追踪原理:Spring web 的拦截器(HandlerInterceptor)+ 阿里的一个开源工具 (TransmittableThreadLocal 支持主线程到线程池的透传)+ feign 的 RequestInterceptor
排查过程
在排查日志之前,我经验告诉我,这大概率是 TTL 的 agent 代理与线上的 arm 监控代理冲突,导致线程池透传 traceId 没生效导致的(我以前也碰到过这类问题)
- 查看每个前端请求接口的日志打印,发现不同的请求确实存在重复的 traceId。

接着,我去看了下打印这行日志的实现,如下图,是通过一个 AOP 切面拦截所有的rest 请求去打印。其中,打印日志使用了线程池。

结论一:证实了我的猜测,线程池透传 traceId 没生效。也就是说,所有接口业务中使用到线程池的都可能会串 traceId。
-
当时我以为这就完了。在一次偶然的排查线上问题中发现,基本在同一时间,没有使用到线程池的两个业务接口,打印的日志的 traceId 是一样的。
我首先想到是,是不是接口请求接口没清除 traceId 呢,也就是没有重写 拦截器的 org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion 方法呢?

我去看一了下源代码,虽然没有重写afterCompletion() 方法在每次请求结束之后清除 traceId,但看 如上的preHandle()方法的代码逻辑,不清除也不要紧,如上代码所示,当在请求头中获取 traceId 不存在时会重新生成一个 traceId。
初步猜测:
1)IdWorker 生成的随机id重复了?
不太可能吧,IdWorker 用的是雪花算法啊,尽管在同一毫秒,并发量不高的话也不会生成重复的…
2) IdWorker 非单例的原因?
结论二:短时间内,存在 IdWorker 生成了重复的 traceId。
解决方案
-
关于第一个线程池透传 traceId 没生效问题。主要有两个原因:
1.1 项目压根就没有对线程池做 TTL 的包装增强(也就是项目启动参数没有加上 TTL 的 agent 方式代理),需要把参数给加上。
-javaagent:D:\AAA_pengyu\respository\com\alibaba\transmittable-thread-local\2.11.5\transmittable-thread-local-2.11.5.jar1.2 实际上,尽管在所有项目把 TTL 的 agent 方式代理启动参数家加上也还是会失效的。前面说了,TTL 的 agent 代理与线上的 arm 监控代理冲突。
针对和阿里云的沟通,修改方案如下:

-
关于 IdWorker 生成了重复的 traceId。
在测试调整过程中,我把IdWorker 改成单例模式之后,也还是会存在 id重复问题。
原因是构造 IdWorker 时 workerId,datacenterId,sequence 都为同一个字符串的原因,IdWorker 生成的 随机id 是依赖这三个参数。
所以不同服务根据当前机器ip、mac 等参数动态生成就好了
最后,经过如上的修改之后,公司的全链路日志追踪就好了。
相关文章:
全链路日志追踪
背景 最近线上的日志全局追踪 traceId 不好使了,不同请求经常出现重复的 traceId,或者通过某个请求的 traceId 追踪搜索,检索出了与该请求完全不相干的日志。我领导叫我去排查解决这个问题,这里我把我排查的过程思路以及如何解决…...
ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)
碎碎念:好久不见,甚是想念!本期带来的是有关ZYNQ7020的内容,我们知道ZYNQ作为一款具有硬核的SOC,PS端很强大,可以更加便捷地实现一些算法验证。本文具体讲解一下里面的TTC定时器,之后发布的Part…...
蓝牙设备如何自定义UUID
如何自定义UUID 所有 BLE 自定义服务和特性必须使用 128 位 UUID 来识别,并且要确保基本 UUID 与 BLE 定义的基本 UUID(00000000-0000-1000-8000-00805F9B34FB)不一样。基本 UUID 是一个 128 位的数值,根据该值可定义标准UUID&am…...
好看的html登录界面,
界面效果: 代码: <!DOCTYPE html> <html><head><title>Login Page</title><style>body {background-color: #f2f2f2;font-family: Arial, sans-serif;}form {background-color: #fff;border-radius: 5px;box-shado…...
Java模拟星空
目录 前言 JavaFX基础 1. GraphicsContext 2. AnimationTimer 代码实现 完整代码 前言 看了Python模拟星空很漂亮,Java也应该必须有一个! 环境:只需要JDK1.8就好!不需要外部包!!! Jav…...
YGG 代表 Web3 Gaming 参加 2023 年游戏开发者大会
Yield Guild Games(YGG)在 2023 年 3 月 20 日至 24 日在加州旧金山举行的游戏开发者大会(GDC)上大显身手,这是游戏开发者的重要交流学习活动。虽然 GDC 本身提供了多种多样的活动,包括讲座、小组讨论、圆桌…...
水库安全运行智慧管理平台解决方案筑牢防汛“安全墙”
解决方案 水库安全运行智慧管理系统解决方案,系统主要由降雨量监测站、水库水位监测站、大坝安全监测中的渗流量、渗流压力和变形监测站及视频和图像监测站等站点组成,同时建立规范、统一的监测平台,集数据传输、信息共享、数据储存于一体&a…...
Exchange升级部署方案
目录 前言 一、需求分析 二、升级前准备 1.备份当前 Exchange Server 数据...
AE开发之图层渲染20210603
AE开发之图层渲染比例符号化地图的整饰唯一值符号的符号化过程点符号设置,线符号设置标注图层,(写得不好,不推荐看) 唯一值符号化,字段进行设置,这里用到了UniqueValueRenderer接口,这里面有一…...
需要了解的过滤器
过滤器 1. 概念 过滤器: 从名字上理解就是对于事件的过滤操作,在web 中的过滤器,就是对于请求进行过滤操作,我们使用过滤器,就可以对于请求进行拦截操作,然后进行响应的处理操作,实现很多的特殊…...
VUE3的setup函数
文章目录 目录 文章目录 前言 一、setup函数是什么? 二、使用步骤 三、vue3中文文档和面向vue3的组件库 总结 前言 Vue3是一个面向数据驱动的渐进式JavaScript框架,其的设计理念包括简洁、灵活和高效。相比Vue2,Vue3的架构设计有很大的不同&…...
停车场管理系统文件录入(C++版)
❤️作者主页:微凉秋意 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆 文章目录一、案例需求描述1.1、汽车信息模块1.2、普通用户模块1.3、管理员用户模块二、案例分析三…...
线程(Thread)的三种等待唤醒机制详解
1、为什么需要线程的等待和唤醒 线程的等待唤醒机制是一种经典的“生产者和消费者”模型。例如食品加工厂,食品加工人员和原料补给人员,在有充足原料时,补给人员是在等待,等到原料不够时,食品加工人员通知补给人员&am…...
从零学习python - 13模块的导入与使用(实现单例模式)
模块基础知识 # 项目 > 包 > 模块 > 变量\方法\类 # 在python中,模块是代码组织的一种方式,把功能相近的函数或类放到一个文件中,一个文件(.py)就是一个模块,模块名就是文件名去掉py后缀. # 好处:提高代码可复用性和可维护性,一个模块编写完成后,很方便在其他项目中导…...
国产SSD、内存卷哭国外大厂,三星宣布减产涨价在路上了
PC 圈有一句话是这么说的:论价格屠夫还得看国产品牌! 可不是嘛,国产长鑫、长江算是彻底将全球存储芯片市场搅局者这一「骂名」坐实了! 不说特别早期,前几年吧,普通单条 8G DDR4 内存都能卖到六七百元&…...
数据库管理-第六十六期 SQL Domain(20230413)
数据库管理 2023-04-13第六十六期 SQL Domain1 基本介绍2 Domain的表达式和条件3 语法4 语义5 示例总结第六十六期 SQL Domain 上一期一笔带过了部分Oracle 23c的新特性,这一期重点讲一下SQL Domain新特性。 【https://docs.oracle.com/en/database/oracle/oracle-…...
《Vue3实战》 第一章 nods/npm安装、配置
1、nods.js安装(Windows) 1.1、下载并安装node https://nodejs.org/en/ , 安装到d盘nodejs目录 1.2、配置环境变量 path配置 1.3、配置全局包存放目录和缓存目录 在根目录下创建node_global(全局包存放目录)和node_cache&…...
JAVA练习104-四数相加 II
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-四数相加 II 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示:这里可以添加本文要记录的大概内容: 4月10日练…...
【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)
六、引用 6.1 引用的概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法上) 格式:类型& 引用变量名(对象名) …...
Redis只用来做缓存?来认识一下它其他强大的能力吧。
当今互联网应用中,随着业务的发展,数据量越来越大,查询效率越来越高,对于时序数据的存储、查询和分析需求也越来越强烈,这时候 Redis 就成为了首选的方案之一。 Redis 提供了多种数据结构,如字符串、哈希表…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
