docs: 问题清单新增问题11-ContextInterceptor响应头未设置traceId和spanId

This commit is contained in:
zhangjf 2026-02-20 16:51:23 +08:00
parent 2c7d304408
commit a6716da742

View File

@ -20,6 +20,7 @@
| 8 | OpenFeign配置 | FeignClient硬编码URL导致Nacos服务发现失效 | 高 | 已解决 | | 8 | OpenFeign配置 | FeignClient硬编码URL导致Nacos服务发现失效 | 高 | 已解决 |
| 9 | Nacos 配置 | Nacos 3.0 客户端缺少 username/password 认证配置 | 高 | 已解决 | | 9 | Nacos 配置 | Nacos 3.0 客户端缺少 username/password 认证配置 | 高 | 已解决 |
| 10 | 连接池监控 | HikariMonitorConfig空指针异常 | 中 | 已解决 | | 10 | 连接池监控 | HikariMonitorConfig空指针异常 | 中 | 已解决 |
| 11 | 链路追踪 | ContextInterceptor响应头未设置traceId和spanId | 高 | 已解决 |
--- ---
@ -666,6 +667,105 @@ public void monitorHikariPool() {
--- ---
### 问题11ContextInterceptor响应头未设置traceId和spanId
#### 问题现象
用户反馈API响应头中没有返回`X-Trace-Id``X-Span-Id`,导致无法通过响应头直接获取追踪标识进行问题排查。
```bash
# 预期响应头
HTTP/1.1 200 OK
X-Trace-Id: abc123def456789abc123def456789ab
X-Span-Id: 1a2b3c4d5e6f7g8h
# 实际响应头(缺失追踪标识)
HTTP/1.1 200 OK
Content-Type: application/json
```
#### 问题原因
`ContextInterceptor.java`文件虽然在Git提交中包含了响应头设置代码但文件实际内容与提交记录不符缺少以下关键代码
```java
// 缺少的代码
public static final String HEADER_SPAN_ID = "X-Span-Id";
// 生成 SpanId
String spanId = TraceContextHolder.getOrCreateSpanId();
// 在响应头中返回 traceId 和 spanId
response.setHeader(HEADER_TRACE_ID, traceId);
response.setHeader(HEADER_SPAN_ID, spanId);
```
#### 解决方案
**修复 `fund-common/src/main/java/com/fundplatform/common/web/ContextInterceptor.java`**
```java
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// ... 其他代码 ...
// 提取或生成 TraceId全链路唯一标识
String traceId = request.getHeader(HEADER_TRACE_ID);
if (traceId != null && !traceId.isEmpty()) {
TraceContextHolder.setTraceId(traceId);
} else {
traceId = TraceContextHolder.getOrCreateTraceId();
}
// 生成 SpanId当前服务处理标识每个请求唯一
String spanId = TraceContextHolder.getOrCreateSpanId();
// 在响应头中返回 traceId 和 spanId方便客户端追踪
response.setHeader(HEADER_TRACE_ID, traceId);
response.setHeader(HEADER_SPAN_ID, spanId);
// ... 其他代码 ...
}
```
**同时需要在 `TraceContextHolder.java` 中添加 SpanId 支持**
```java
private static final ThreadLocal<String> SPAN_ID_HOLDER = new ThreadLocal<>();
private static final String MDC_KEY_SPAN_ID = "spanId";
public static void setSpanId(String spanId) {
SPAN_ID_HOLDER.set(spanId);
MDC.put(MDC_KEY_SPAN_ID, spanId);
}
public static String getSpanId() {
return SPAN_ID_HOLDER.get();
}
public static String getOrCreateSpanId() {
String spanId = SPAN_ID_HOLDER.get();
if (spanId == null || spanId.isEmpty()) {
spanId = generateSpanId();
setSpanId(spanId);
}
return spanId;
}
public static String generateSpanId() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
}
```
#### 修复文件
- `fund-common/src/main/java/com/fundplatform/common/context/TraceContextHolder.java`
- `fund-common/src/main/java/com/fundplatform/common/web/ContextInterceptor.java`
#### 经验总结
- **文件提交后需验证实际内容**不能仅依赖Git提交记录
- **代码审查时需检查文件实际内容**,确保修改确实生效
- **响应头设置应在 preHandle 中完成**,确保所有请求都能返回追踪标识
---
## 预防措施清单 ## 预防措施清单
### 前后端接口对接 ### 前后端接口对接
@ -697,6 +797,7 @@ public void monitorHikariPool() {
| **FeignClient 配置** | **有注册中心时必须移除 url 属性,仅保留 name** | | **FeignClient 配置** | **有注册中心时必须移除 url 属性,仅保留 name** |
| **Nacos 3.0 认证** | **客户端必须配置 username 和 password默认都是 nacos** | | **Nacos 3.0 认证** | **客户端必须配置 username 和 password默认都是 nacos** |
| **定时任务资源检查** | **定时任务访问资源前需检查资源是否已初始化(如连接池)** | | **定时任务资源检查** | **定时任务访问资源前需检查资源是否已初始化(如连接池)** |
| **链路追踪响应头** | **API响应必须返回X-Trace-Id和X-Span-Id便于客户端追踪** |
### 功能开发流程 ### 功能开发流程
@ -725,6 +826,8 @@ public void monitorHikariPool() {
- `fund-report/src/main/java/com/fundplatform/report/feign/ProjectFeignClient.java` - 移除硬编码 URL使用 Nacos 服务发现 - `fund-report/src/main/java/com/fundplatform/report/feign/ProjectFeignClient.java` - 移除硬编码 URL使用 Nacos 服务发现
- `fund-cust/src/main/java/com/fundplatform/cust/feign/SysServiceClient.java` - 移除硬编码 URL使用 Nacos 服务发现 - `fund-cust/src/main/java/com/fundplatform/cust/feign/SysServiceClient.java` - 移除硬编码 URL使用 Nacos 服务发现
- `fund-*/src/main/resources/application.yml` - 为所有业务模块添加 Nacos 3.0 username/password 认证配置 - `fund-*/src/main/resources/application.yml` - 为所有业务模块添加 Nacos 3.0 username/password 认证配置
- `fund-common/src/main/java/com/fundplatform/common/context/TraceContextHolder.java` - 添加 SpanId 支持
- `fund-common/src/main/java/com/fundplatform/common/web/ContextInterceptor.java` - 响应头设置 traceId 和 spanId
**前端文件:** **前端文件:**
- `fund-admin/vite.config.ts` - 代理配置修复 - `fund-admin/vite.config.ts` - 代理配置修复
@ -749,6 +852,7 @@ public void monitorHikariPool() {
| `服务发现失效` | FeignClient 硬编码 URL | 移除 url 属性,仅保留 name 使用 Nacos 发现 | | `服务发现失效` | FeignClient 硬编码 URL | 移除 url 属性,仅保留 name 使用 Nacos 发现 |
| `Nacos 注册失败 (认证错误)` | 缺少 username/password 配置 | 在 discovery 节点添加 username 和 password | | `Nacos 注册失败 (认证错误)` | 缺少 username/password 配置 | 在 discovery 节点添加 username 和 password |
| `HikariPoolMXBean NullPointerException` | 定时任务执行时连接池未初始化 | 添加 poolMXBean 空值检查 | | `HikariPoolMXBean NullPointerException` | 定时任务执行时连接池未初始化 | 添加 poolMXBean 空值检查 |
| `响应头缺失X-Trace-Id/X-Span-Id` | ContextInterceptor未设置响应头 | 在preHandle中调用response.setHeader() |
--- ---