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

【全链路追踪】XXL-JOB添加TraceID

文章目录

  • 一、背景
    • 调用路径
    • 部署环境
    • 问题
  • 二、方案
  • 三、Demo示例
    • 1、MDC
    • 2、RequestInterceptor
    • 3、HandlerInterceptor
    • 4、logback.xml
  • 四、后续改进思路

一、背景

首先这个项目属于小型项目,由于人手以及时间限制,并未引入Skywalking等中间件来做调用链路追踪。Skywalking不在此次的讨论范围中。

其次介绍一下项目的相关背景

调用路径

项目中主要有两种调用路径

  1. Web请求走统一的网关入口,调用后端服务
  2. XXL-JOB定时任务执行调度

部署环境

Kubernetes

问题

走统一网关入口的请求不用担心,在网关那边加了TraceID,但是XXL-JOB由于是自动注册,且部署环境是在K8S内,XXL-JOB获取到的是Pod的IP,网关并未拦截到。
由于项目的逻辑较为复杂,XXL-JOB的调度任务属于其中比较重要的一块,对于前期开发的调试以及后期问题的确认,加上TraceID是非常有必要的。

二、方案

首先确认是的XXLJOB执行定时任务时,JobHandler没有TraceID,不考虑使用中间件的话,就只有两种方案了。

一种是改造XXL-JOB源码,在发起请求中添加TraceID;另一种则是在后端服务拦截到XXL-JOB的请求,在入口添加TraceID。

XXL-JOB的源码没有具体研究过,之前只是做过适配Oracle,改造起来有一定难度,所以最后采用的方案还是在后端服务拦截请求,添加TraceID。

在网上搜索了一下相关资料,发现实现起来还是比较简单的,一般都是通过spring aop的方式,在Slf4j的MDC中添加TraceID。
在这里简单介绍下MDC,之前我也没做过更多了解。

MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。某些应用程序采用多线程的方式来处理多个用户的请求。

MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问当需要记录日志时,只需要从 MDC 中获取所需的信息即可。

其实就是使用ThreadLocal来存储,而由于请求到Java后端服务时,Tomcat会分配一个线程,直至请求结束,这样就会保证我们在入口添加的TraceID,会传递到整条链路。
但是使用MDC调用存在两个问题:

  1. 子线程中日志TraceID丢失

  2. 跨服务调用日志TraceID丢失

同时项目中使用了Openfeign,在发起端使用 RequestInterceptor 来拦截,添加TraceID,然后在接收端使用 HandlerInterceptor 拦截。

即最终方案是 MDC+RequestInterceptor+HandlerInterceptor

整体的调用链路如下:

暂时无法在飞书文档外展示此内容

三、Demo示例

1、MDC

@Aspect
@Component
@Slf4j
public class XxlJobAopConfig {@Before("@annotation(com.xxl.job.core.handler.annotation.XxlJob)")public void beforeMethod() {MDC.put('traceId',UUID.randomUUID().toString().toLowerCase());}
}

2、RequestInterceptor

@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {template.header('traceId', MDC.get(HeaderExtraInfoConstants.traceId));}
}
@FeignClient(name = "test", url = "xxx", configuration = FeignRequestInterceptor.class)

3、HandlerInterceptor

@Slf4j
@Component
public class HeaderInterceptor implements HandlerInterceptor {@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception arg3) {MDC.remove('traceId');}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView arg3) {}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String traceId = request.getHeader(HeaderExtraInfoConstants.traceId);if (StringUtils.isEmpty(traceId)) {MDC.put('traceId', UUID.randomUUID().toString().toLowerCase());} else {MDC.put('traceId', traceId);}return true;}}
@Configuration
public class InterceptorConfiguration extends WebMvcConfigurationSupport {@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new HeaderInterceptor()).addPathPatterns("/**");}
}

4、logback.xml

%d{yyyy-MM-dd HH:mm:ss.SSS} ---> [%X{traceId}] ---> [%thread] ---> %-5level %logger{50} - %msg%n

四、后续改进思路

上述方案有较大的局限性,只适用于服务间通过feign调用的方式,如果有其他如okhttp的方式,需要再添加拦截器。对于多线程的问题也并未解决,常见的方式是通过重写线程池来解决。

  1. 丰富调用场景,添加拦截器

  2. 重写线程池

  3. 由于部署在K8S集群,可启用Istio进行服务治理

相关文章:

【全链路追踪】XXL-JOB添加TraceID

文章目录 一、背景调用路径部署环境问题 二、方案三、Demo示例1、MDC2、RequestInterceptor3、HandlerInterceptor4、logback.xml 四、后续改进思路 一、背景 首先这个项目属于小型项目,由于人手以及时间限制,并未引入Skywalking等中间件来做调用链路追…...

[Unity]Lua本地时间、倒计时和正计时。

惯例,直接上代码: --正计时开始时的时间戳 self.begin_time os.time() --倒计时时长,01:30:00 self.countdown_time 5400 --是否开始计时 self.is_update_local_time true--Unity Update function time_transition:update_local_timer()i…...

探究HTTP API接口测试:工具、方法与自动化

本文将深入探讨HTTP API接口测试的重要性,并介绍了相关工具、方法以及自动化测试的实施,同时比较了HTTP和API接口测试的区别。从不同角度解析这一关键测试领域,帮助读者更好地理解和应用于实际项目中。 在如今数字化的世界中,软件…...

CSS中如何实现文字溢出省略号(text-overflow: ellipsis)效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS中如何实现文字溢出省略号(text-overflow: ellipsis)效果?⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 …...

CSDN编程题-每日一练(2023-08-21)

CSDN编程题-每日一练(2023-08-21) 一、题目名称:贝博士的论文审阅统计二、题目名称:生命进化书三、题目名称:寻找宝藏山一、题目名称:贝博士的论文审阅统计 时间限制:1000ms内存限制:256M 题目描述: 贝博士经常收到申请他审阅论文的信函,每封信函的信封上面只有两个申…...

面试题-React(四):React中的事件绑定如何实现?有几种方式?

一、React事件绑定机制 在React中,事件绑定是通过JSX语法来实现的。你可以将事件处理函数直接绑定到元素的属性上,比如onClick、onMouseOver等。当触发相应事件时,绑定的事件处理函数将被调用。 React采用了一种合成事件(Synthe…...

Docker容器:docker镜像的创建及dockerfile案例

文章目录 一.docker镜像的三种创建方法1.基于现有镜像创建1.1 启动镜像1.2 生成新镜像 2.基于本地模板创建2.1 OPENVZ 下载模板2.2 导入容器生成镜像 3.基于dockerfile创建3.1 dockerfile结构及分层3.2 联合文件系统3.3 docker镜像加载原理及过程 4.dockerfile操作常用的指令4.…...

Java虚拟机(JVM):引用计数算法

一、引言 我们学习了Java内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭。栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来就已知的…...

【AGC】Publishing api怎么上传绿色认证审核材料

【问题描述】 华为应用市场会对绿色应用标上特有的绿色标识,代表其通过华为终端开放实验室DevEco云测平台的兼容性、稳定性、安全、功耗和性能的检测和认证,是应用高品质的象征。想要自己的应用认证为绿色应用就需要在发布应用时提供绿色认证审核材料&a…...

改变住宅区空气质量,你一定要知道!

在现代城市生活中,住宅区的环境质量对居民的健康和舒适感起着至关重要的作用。扬尘颗粒和噪声不仅直接影响人们的日常生活,还可能对居民的健康和生活品质造成持续的影响。 在不断提升环保意识的同时,政府、社区和居民也将共同努力&#xff0c…...

【SpringCloud】Gateway使用

文章目录 概述阻塞式处理模型和非阻塞处理模型概念阻塞式处理模型 三大核心概念 工作流程使用POMYML启动类配置路由通过编码进行配置动态路由常用的Route Predicate自定义全局过滤器自定义filter 官网 https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1…...

Spring之域对象共享数据

文章目录 前言一、requset域1.使用ServletAPI向request域对象共享数据2.使用ModelAndView向request域对象共享数据3.使用Model向request域对象共享数据4.使用map向request域对象共享数据5.使用ModelMap向request域对象共享数据6.Model、ModelMap、Map的关系 二、session域向ses…...

Redis巩固加强(帮助迅速梳理知识,同时适用初学者理解)

目录 Redis究竟是什么 Redis为什么能够做到这么快 Redis持久化机制 Redis如何实现过期的key的删除 Redis数据类型及应用场景 Redis的缓存穿透如何解决 什么是缓存穿透? 解决方案: 布隆过滤器 Redis如何解决缓存雪崩 什么是缓存雪崩 措施 Redis…...

Sui生态项目|集隐私通信、移动钱包、链上朋友圈和红包功能一体的社交应用ComingChat

ComingChat是在Sui网络上构建的去中心化社交平台,功能众多,其中加密聊天功能为用户提供了安全的沟通方式。该功能利用了Signal加密协议,这是一种在Signal、WhatsApp和Skype等应用中广受欢迎的开源软件协议。 ComingChat在Sui上提供了全面的…...

I2S/PCM board-level 约束及同步(latencyskewbitsync)

I2S/PCM是典型的低速串口,在两个方向上分别有两组信号,我们已soc为视角分为soc-adif和外设audio-codec。 那么adif输入: sclk_i, ws_i, sdi 当然并不是三个输入信号同时有效,只有adif RX slave时,三个输入都会有效…...

vue 富文本编辑器

安装 1、npm install wangeditor/editor --save 2、npm install wangeditor/editor-for-vue --save使用 .vue文件//展示<div style"border: 1px solid #ccc;width: 95%;"><!-- 工具栏 --><Toolbar style"border-bottom: 1px solid #ccc" …...

为什么说ChatGPT还不是搜索引擎的对手

一 前言 1950年&#xff0c;英国科学家图灵在一篇论文中预言&#xff0c;人类有可能创造出具有真正智能的机器。 著名的「图灵测试」就此诞生&#xff1a;如果一台机器能够与人类展开对话&#xff0c;而不被辨别出其机器身份&#xff0c;那么称这台机器具有智能。 也是从那时…...

2308C++协程流程

参考 #include <常用> #include <协程> #include "简异中.cpp" //用来中文定义的.元<类 T>构 同步{共针<T>值;同步(共针<T>p):值(p){输出<<"构建同步"<<行尾;//.8}同步(常 同步&s):值(s.值){输出<<&…...

C#实现稳定的ftp下载文件方法

当使用C#实现稳定的FTP下载文件的方法时&#xff0c;我们可以使用FtpWebRequest类来执行FTP操作&#xff0c;并根据需要添加错误处理和重试机制。下面是一个示例代码&#xff1a; using System; using System.IO; using System.Net;public class FTPDownloader {private const…...

八股文之计算机网络

TCP/IP 网络模型有哪几层 该模型用来解决不同设备间的进程通信&#xff0c;就需要网络通信&#xff0c;该模型就应运而生。首先是应用层&#xff0c;我们所接触的App都是在这一层实现的&#xff0c;当不同的设备需要通信时&#xff0c;就需要把数据发给传输层&#xff0c;传输…...

kotlin 比较 let apply

let 和 apply 是 Kotlin 标准库中的两个非常有用的函数&#xff0c;它们用于在代码中实现更简洁和可读的操作。它们通常在函数式编程和链式调用中使用&#xff0c;以简化代码并提高可维护性。下面是关于这两个函数的详细解释&#xff1a; let let 函数是一个作用域函数&#…...

springboot跨域踩坑笔记

事情是这样的&#xff0c;我在进行前后端联调的时候&#xff0c;发送了跨域拦截 马上在spring项目中创建一个CorsConfig类 package com.example.demo.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.an…...

基于STM32+FreeRTOS的四轴机械臂

目录 代码&#xff1a; 注释写的较少&#xff0c;但本文出现的代码都有注释&#xff0c;所以请直接在本文里看注释 项目概述&#xff1a; 一 准备阶段&#xff08;都是些废话&#xff09; 二 裸机测试功能 1.摇杆控制 接线&#xff1a; CubeMX配置&#xff1a; 代码 2…...

【C语言】三子棋游戏——超细教学

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 &#x1f525;该篇将结合之前的知识来实现 三子棋游戏。 目录&#xff1a; &#x1f31f;思路框架&#xff1a;测试游戏 &#x1f31f…...

redux的介绍、安装、三大核心与执行流程

redux的介绍、安装、三大核心与执行流程 一、redux的基本介绍二、redux的安装三、redux核心概念3.1 action3.2 reducer3.3 store 四、Redux代码执行流程五、加减案例练习 一、redux的基本介绍 redux中文官网Redux 是 React 中最常用的状态管理工具&#xff08;状态容器&#x…...

Redis 5环境搭建

一、环境搭建 如果是Centos8&#xff0c;yum 仓库中默认的 Redis版本就是5&#xff0c;直接yum install即可。如果是Centos7&#xff0c;yum 仓库中默认的 Redis版本是3系列&#xff0c;比较老~ 为了我们能在 Centos7中下载到 Redis5 首先要安装额外的软件源 sudo yum insta…...

stm32红绿灯源代码示例(附带Proteus电路图)

本代码不能直接用于红路灯&#xff0c;只是提供一个思路 #include "main.h" #include "gpio.h" void SystemClock_Config(void); void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOB_CLK_ENAB…...

Qt与电脑管家4

折线图&#xff1a; #ifndef LINE_CHART_H #define LINE_CHART_H#include <QWidget> #include <QPainter> #include "circle.h" class line_chart : public QWidget {Q_OBJECT public:explicit line_chart(QWidget *parent nullptr); protected:void pa…...

使用css美化gradio界面

基本方法 在默认的前端页面中使用检查工具确定要修改的部分的选择器名称&#xff0c;然后在block_css中对其修改&#xff0c;并在启动网页时传入参数&#xff1a;with gr.Blocks(cssblock_css, thememy_theme) as demo: 禁止修改下拉框文字 input.border-none.svelte-c0u3f0…...

Flink流批一体计算(13):PyFlink Tabel API之SQL DDL

1. TableEnvironment 创建 TableEnvironment from pyflink.table import Environmentsettings, TableEnvironment# create a streaming TableEnvironmentenv_settings Environmentsettings.in_streaming_mode()table_env TableEnvironment.create(env_settings)# or create…...

天猫网站左侧导航用js怎么做/seo推广怎么样

方法有点笨&#xff0c;但是&#xff0c;没有找到好一点的办法&#xff0c;就这样先装着&#xff0c;看朋友们是否也有需要&#xff0c;记录一下 CentOS 下安装MySQL5.7的时候出现各种问题&#xff0c;各种报错&#xff0c;试过无数办法&#xff0c;今天终于安装上去&#xff0…...

wordpress默认编辑器设置/网络软文是什么

代码(java)已经分享在Github上:https://github.com/CCSClassBattlecruiser/660div2个人水平有限,如有错误还请在评论区指出 谢谢!Problem A. Captain Flint and Crew Recruitmenthttps://codeforces.com/contest/1388/problem/A题目大意: 如果一个整数x可以被表示成两个质数p和…...

免费手机网站app/网络推广员是什么工作

点击上方“Python大本营”&#xff0c;选择“置顶公众号” Python大本营 IT人的职业提升平台Python经过了几十年的努力才得到了编程社区的赏识。自2010年以来&#xff0c;Python得到了蓬勃发展&#xff0c;并且在2019至2020年更是经常霸占每月PYPL编程榜榜首位置&#xff01;但…...

网站扩展虚拟空间/软件培训机构有哪些?哪个比较好

已经有了一次web项目的开发经验&#xff0c;给自己单一的编程生涯增添了一些色彩。但是自己终归是C工程师&#xff0c;于是在那次web开发后又重回C项目开发中了。1.公司最大项目——某综合性系统公司要做一个客户端有数个应用系统的大型综合平台。有客户端&#xff0c;自然就得…...

可以用服务器做网站/国内新闻摘抄

作为一名SEO人员&#xff0c;我们每天都会遇到各种千奇百怪的事情&#xff0c;但这些新问题&#xff0c;往往都是因为自己的小疏忽所造成的&#xff0c;比如&#xff1a;我们偶尔在利用site命令查询网站收录情况的时候&#xff0c;偶尔会遇到一个情况&#xff1a;网页展现的内容…...

ipv6网站建设东莞/百度客服中心人工在线咨询

问题&#xff1a;使用securecrt ssh到linux之后&#xff0c;backspace(退格键)&#xff0c;delete(删除键)&#xff0c;以及4个方向键都为乱码&#xff0c;不能正常使用。按tab键也没有自动补全文件名。 即&#xff1a; 按Backspace(退格键)和delete(删除键)屏幕显示的是&#…...