当前位置: 首页 > article >正文

【服务日志链路追踪】

MDC+InheritableThreadLocal和spring cloud sleuth

在微服务架构中,日志链路追踪(Logback + Distributed Tracing) 是一个关键需求,主要用于跟踪请求在不同服务间的调用链路,便于排查问题。常见的实现方案有两种:

手动方案(MDC + InheritableThreadLocal)

自动化方案(Spring Cloud Sleuth + Zipkin/Jaeger)

下面从 Logback 日志集成 的角度,对比这两种方案的实现方式、优缺点及适用场景。

  1. 手动方案:MDC + InheritableThreadLocal
    核心组件
    MDC(Mapped Diagnostic Context)

Logback 提供的线程本地存储,用于存放日志变量(如 traceId)。

日志输出时自动携带 MDC 中的字段(需配置 %X{traceId})。

InheritableThreadLocal

解决异步线程(如线程池、@Async)无法继承 MDC 的问题。

实现步骤
(1) 定义 TraceContext(管理 traceId)

public class TraceContext {private static final InheritableThreadLocal<String> TRACE_ID = new InheritableThreadLocal<>();public static void setTraceId(String traceId) {TRACE_ID.set(traceId);MDC.put("traceId", traceId); // 存入 MDC,Logback 自动输出}public static String getTraceId() {return TRACE_ID.get();}public static void clear() {TRACE_ID.remove();MDC.remove("traceId");}
}

(2) 拦截器设置 traceId(HTTP 请求入口)

public class TraceInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String traceId = request.getHeader("X-Trace-Id") != null ? request.getHeader("X-Trace-Id") : UUID.randomUUID().toString();TraceContext.setTraceId(traceId);return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {TraceContext.clear(); // 防止内存泄漏}
}

(3) Logback 配置(输出 traceId)

<!-- logback-spring.xml -->
<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /></root>
</configuration>

日志示例:

14:25:30.456 [http-nio-8080-exec-1] [abc123] INFO  com.example.demo.Controller - Request received

(4) 异步线程支持(线程池需额外处理)

// 普通线程
new Thread(() -> {log.info("Async task"); // 能继承 traceId
}).start();// 线程池需使用 TransmittableThreadLocal(阿里开源库)
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {log.info("ThreadPool task"); // 默认会丢失 traceId!
});

在这里插入图片描述
TransmittableThreadLocal vs InheritableThreadLocal
在这里插入图片描述

  1. 自动化方案:Spring Cloud Sleuth + Logback
    核心组件
    Spring Cloud Sleuth

自动生成 traceId 和 spanId,并通过 MDC 输出到日志。

支持 HTTP(Feign/RestTemplate)、MQ(Kafka/RabbitMQ)、gRPC 等自动传播。

Logback 集成

Sleuth 自动填充 MDC,无需手动管理。

实现步骤
(1) 引入依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- 可选:上报到 Zipkin -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

(2) Logback 配置(自动携带 traceId)

<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId:-}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /></root>
</configuration>

日志示例(Sleuth 自动填充 traceId 和 spanId):

<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId:-}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /></root>
</configuration>

(3) 跨服务调用(自动传播 traceId)
HTTP(Feign):自动添加 X-B3-TraceId Header。

MQ(Kafka):消息头自动携带追踪信息。

在这里插入图片描述

  1. 对比总结
    在这里插入图片描述

  2. 推荐选择
    简单项目:使用 MDC + InheritableThreadLocal(或 TransmittableThreadLocal)。

微服务架构:直接上 Spring Cloud Sleuth(或 OpenTelemetry),减少维护成本。

相关文章:

【服务日志链路追踪】

MDCInheritableThreadLocal和spring cloud sleuth 在微服务架构中&#xff0c;日志链路追踪&#xff08;Logback Distributed Tracing&#xff09; 是一个关键需求&#xff0c;主要用于跟踪请求在不同服务间的调用链路&#xff0c;便于排查问题。常见的实现方案有两种&#x…...

【行测】判断推理:图形推理

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;读不在三更五鼓&#xff0c;功只怕一曝十寒。 > 目标&#xff1a;掌握 图形推理 基本题型&#xff0c;并能运用到例题中。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! …...

OpenCV 图形API(12)用于计算图像或矩阵的平均值函数mean()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算矩阵元素的平均值&#xff08;均值&#xff09;。 mean函数计算矩阵元素的平均值M&#xff0c;每个通道独立计算&#xff0c;并返回该值。 …...

Oracle触发器使用(一):DML触发器

Oracle触发器使用(一):DML触发器 DML触发器条件谓词触发器INSTEAD OF DML触发器复合DML触发器Oracle数据库中的触发器(Trigger)本质上也是PL/SQL代码,触发器可以被Enable或者Disable,但是不能像存储过程那样被直接调用执行。 触发器不能独立存在,而是定义在表、视图、…...

3D模型给可视化大屏带来了哪些创新,都涉及到哪些技术栈。

一、3D 模型给可视化大屏带来的创新 更直观的视觉体验 传统的可视化大屏主要以二维图表和图形的形式展示数据&#xff0c;虽然能够传达一定的信息&#xff0c;但对于复杂的场景和数据关系&#xff0c;往往难以直观地呈现。而 3D 模型可以将数据以三维立体的形式展示出来&#…...

Unity HDRP管线用ShaderGraph还原Lit,方便做拓展;

里面唯一的重点就是判断有无这张复合图&#xff0c;我用的是颜色判断&#xff1a; float Tex TexCol.r*TexCol.g*TexCol.b*TexCol.a; if(Tex 1) { IsOrNot 1; } else { IsOrNot 0; } 其他的正常解码就行&#xff0c;对了法线贴图孔位记得设置成normal&#xff0c;不然的话…...

绝缘升级 安全无忧 金能电力环保绝缘胶垫打造电力安全防护新标杆

在电力安全领域&#xff0c;一块看似普通的胶垫&#xff0c;却是守护工作人员生命安全的“第一道防线”。近年来&#xff0c;随着电网设备升级和环保要求趋严&#xff0c;传统绝缘胶垫有异味、易老化、绝缘性能不足等问题逐渐暴露。为此&#xff0c;金能电力凭借技术创新推出新…...

Linux命令-iotop

iotop 命令 iotop 是一个用于实时监控磁盘 I/O 活动的工具&#xff0c;可以显示哪些进程正在使用磁盘资源。 参数 描述 –version 显示程序版本号并退出 -h, --help 显示此帮助消息并退出 -o, --only 仅显示实际进行 I/O 操作的进程或线程 -b, --batch 非交互模式&#xff0c;适…...

记录 | Android getWindow().getDecorView().setSystemUiVisibility(...)设置状态栏属性

纯纯的一边开发一边学习&#xff0c;是小白是菜鸟&#xff0c;单纯的记录和学习&#xff0c;大神勿喷&#xff0c;理解有错望指正&#xff5e; getWindow().getDecorView().setSystemUiVisibility(…) 该方法用于控制系统 UI&#xff08;如状态栏、导航栏&#xff09;的可见性…...

QTableWidget 中insertRow(0)(头插)和 insertRow(rowCount())(尾插)的性能差异

一、目的 在 Qt 的 QTableWidget 中&#xff0c;insertRow(0) &#xff08;头插&#xff09;和 insertRow(rowCount())&#xff08;尾插&#xff09;在性能上存在显著差异。 二、QAbstractItemModel:: insertRows 原文解释 QAbstractItemModel Class | Qt Core 5.15.18 AI 解…...

用nodejs连接mongodb数据库对标题和内容的全文本搜索,mogogdb对文档的全文本索引的设置以及用node-rs/jieba对标题和内容的分词

//首先我们要在Nodejs中安装 我们的分词库node-rs/jieba,这个分词不像jieba安装时会踩非常多的雷&#xff0c;而且一半的机率都是安装失败&#xff0c;node-rs/jieba比jieba库要快20-30%&#xff1b;安装分词库是为了更好达到搜索的效果 这个库直接npm install node-rs/jieba即…...

【万字总结】前端全方位性能优化指南(完结篇)——自适应优化系统、遗传算法调参、Service Worker智能降级方案

前言 自适应进化宣言 当监控网络精准定位病灶&#xff0c;真正的挑战浮出水面&#xff1a;系统能否像生物般自主进化&#xff1f; 五维感知——通过设备传感器实时捕获环境指纹&#xff08;如地铁隧道弱光环境自动切换省电渲染&#xff09; 基因调参——150个性能参数在遗传算…...

不绕弯地解决文件编码问题,锟斤拷烫烫烫

安装python对应库 pip install chardet 检测文件编码 import chardet# 检测文件编码 file_path rC:\Users\AA\Desktop\log.log # 这里放文件和文件绝对路径 with open(file_path, rb) as f:raw_data f.read(100000) # 读取前10000个字节result chardet.detect(raw_data)e…...

高密度任务下的挑战与破局:数字样机助力火箭发射提效提质

2025年4月1日12时&#xff0c;在酒泉卫星发射中心&#xff0c;长征二号丁运载火箭顺利升空&#xff0c;成功将一颗卫星互联网技术试验卫星送入预定轨道&#xff0c;发射任务圆满完成。这是长征二号丁火箭的第97次发射&#xff0c;也是长征系列火箭的第567次发射。 执行本次任务…...

QT Quick(C++)跨平台应用程序项目实战教程 6 — 弹出框

目录 1. Popup组件介绍 2. 使用 上一章内容完成了音乐播放器程序的基本界面框架设计。本小节完成一个简单的功能。单击该播放器顶部菜单栏的“关于”按钮&#xff0c;弹出该程序的相关版本信息。我们将使用Qt Quick的Popup组件来实现。 1. Popup组件介绍 Qt 中的 Popup 组件…...

【面试篇】Es

基础概念类 问题&#xff1a;请简要介绍 Elasticsearch 是什么&#xff0c;它的主要特点有哪些&#xff1f; 答案&#xff1a;Elasticsearch 是一个基于 Lucene 库的开源分布式搜索引擎和分析引擎。它能对海量数据进行实时搜索与分析&#xff0c;被广泛应用于日志分析、全文搜…...

KisFlow-Golang流式实时计算案例(四)-KisFlow在消息队列MQ中的应用

Golang框架实战-KisFlow流式计算框架专栏 Golang框架实战-KisFlow流式计算框架(1)-概述 Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上) Golang框架实战-KisFlow流式计算框架(3)-项目构建/基础模块-(下) Golang框架实战-KisFlow流式计算框架(4)-数据流 Golang框…...

leetcode:1582. 二进制矩阵中的特殊位置(python3解法)

难度&#xff1a;简单 给定一个 m x n 的二进制矩阵 mat&#xff0c;返回矩阵 mat 中特殊位置的数量。 如果位置 (i, j) 满足 mat[i][j] 1 并且行 i 与列 j 中的所有其他元素都是 0&#xff08;行和列的下标从 0 开始计数&#xff09;&#xff0c;那么它被称为 特殊 位置。 示…...

大型语言模型的智能本质是什么

大型语言模型的智能本质是什么 基于海量数据的统计模式识别与生成系统,数据驱动的语言模拟系统 ,其价值在于高效处理文本任务(如写作、翻译、代码生成),而非真正的理解与创造 大型语言模型(如GPT-4、Claude等)的智能本质可概括为基于海量数据的统计模式识别与生成系统,…...

linux_sysctl_fs_file_nr监控项

在 Linux 系统中&#xff0c;/proc/sys/fs/file-nr 文件提供了当前系统打开文件句柄的信息。如果监控到文件打开数较高&#xff0c;可能会影响系统性能&#xff0c;甚至导致无法打开新文件&#xff08;达到文件句柄上限&#xff09;。以下是分析和解决该问题的步骤&#xff1a;…...

Cline – OpenRouter 排名第一的CLI 和 编辑器 的 AI 助手

Cline – OpenRouter 排名第一的CLI 和 编辑器 的 AI 助手&#xff0c;Cline 官网&#xff1a;https://github.com/cline/cline Star 37.8k ps&#xff0c;OpenRouter的网址是&#xff1a;OpenRouter &#xff0c;这个排名第一&#xff0c;据我观察&#xff0c;是DeepSeek v3…...

Mock.js虚拟接口

Vue3中使用Mock.js虚拟接口数据 一、创建项目 pnpm创建vite的项目,通过 PNPM来简化依赖管理。若还没有安装 PNPM&#xff0c;可以通过 npm来安装&#xff1a; 安装 PNPM npm install -g pnpm//使用国内镜像加速pnpm add -g pnpmlatestpnpm config set registry http://regis…...

2025年嵌入式大厂春招高频面试真题及解析

以下是 2025 年嵌入式大厂春招高频面试真题及解析,结合真题分类和核心知识点整理: 一、‌C/C++编程基础‌ ‌1.1 指针与内存‌ ‌野指针的成因及避免方法‌(未初始化、释放后未置空)‌ malloc与calloc的区别(后者自动初始化为0)‌ ‌指针与数组的区别‌(内存分配方…...

LoRa模块通信距离优化:如何实现低功耗覆盖30公里无线传输要求

在物联网&#xff08;IoT&#xff09;快速发展的今天&#xff0c;LoRa&#xff08;Long Range&#xff09;技术作为一种基于扩频调制的远距离无线通信技术&#xff0c;因其远距离通信、低功耗和强抗干扰能力等优势&#xff0c;在农业监测、城市智能管理、环境监测等多个领域得到…...

OpenCV 从入门到精通(day_05)

1. 模板匹配 1.1 什么是模板匹配 模板匹配就是用模板图&#xff08;通常是一个小图&#xff09;在目标图像&#xff08;通常是一个比模板图大的图片&#xff09;中不断的滑动比较&#xff0c;通过某种比较方法来判断是否匹配成功。 1.2 匹配方法 rescv2.matchTemplate(image, …...

Linux操作系统与冯·诺依曼体系结构详解

一、冯诺依曼体系结构 1. 基本概念与历史背景 冯诺依曼体系结构是由数学家约翰冯诺依曼于1945年提出的计算机设计方案&#xff0c;也称为"存储程序计算机"。这一设计奠定了现代计算机的基础架构&#xff0c;至今仍是大多数计算机系统的核心设计理念。 2. 冯诺依曼体…...

OpenRouter开源的AI大模型路由工具,统一API调用

简介 ‌OpenRouter是一个开源的路由工具‌&#xff0c;它可以绕过限制调用GPT、Claude等国外模型。以下是对它的详细介绍&#xff1a; 一、主要功能 OpenRouter专注于将用户请求智能路由到不同的AI模型&#xff0c;并提供统一的访问接口。它就像一个“路由器”&#xff0c;能…...

qt tcpsocket编程遇到的并发问题

1. 单个socket中接收消息的方法要使用局部变量而非全局&#xff0c;避免消息频发时产生脏数据 优化后的关键代码 recieveInfo() 方法通过返回内部处理后的 msg 进行传递if (data.indexOf("0103") -1) { 这里增加了判断, 对数据&#xff08;非注册和心跳&#xff0…...

zabbix监控网站(nginx、redis、mysql)

目录 前提准备&#xff1a; zabbix-server主机配置&#xff1a; 1. 安装数据库 nginx主机配置&#xff1a; 1. 安装nginx redis主机配置&#xff1a; 1. 安装redis mysql主机配置&#xff1a; 1. 安装数据库 zabbix-server&#xff1a; 1. 安装zabbix 2. 编辑配置文…...

蓝桥杯冲刺

例题1&#xff1a;握手问题 方法1&#xff1a;数学推理(简单粗暴&#xff09; 方法2&#xff1a;用代码实现方法1 #include<iostream> using namespace std; int main() {int result 0;for (int i 1; i < 49; i){for (int j i 1; j < 50; j){//第i个人与第j个…...