docs: 问题清单新增问题11-ContextInterceptor响应头未设置traceId和spanId
This commit is contained in:
parent
2c7d304408
commit
a6716da742
104
doc/开发问题清单.md
104
doc/开发问题清单.md
@ -20,6 +20,7 @@
|
||||
| 8 | OpenFeign配置 | FeignClient硬编码URL导致Nacos服务发现失效 | 高 | 已解决 |
|
||||
| 9 | Nacos 配置 | Nacos 3.0 客户端缺少 username/password 认证配置 | 高 | 已解决 |
|
||||
| 10 | 连接池监控 | HikariMonitorConfig空指针异常 | 中 | 已解决 |
|
||||
| 11 | 链路追踪 | ContextInterceptor响应头未设置traceId和spanId | 高 | 已解决 |
|
||||
|
||||
---
|
||||
|
||||
@ -666,6 +667,105 @@ public void monitorHikariPool() {
|
||||
|
||||
---
|
||||
|
||||
### 问题11:ContextInterceptor响应头未设置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** |
|
||||
| **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-cust/src/main/java/com/fundplatform/cust/feign/SysServiceClient.java` - 移除硬编码 URL,使用 Nacos 服务发现
|
||||
- `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` - 代理配置修复
|
||||
@ -749,6 +852,7 @@ public void monitorHikariPool() {
|
||||
| `服务发现失效` | FeignClient 硬编码 URL | 移除 url 属性,仅保留 name 使用 Nacos 发现 |
|
||||
| `Nacos 注册失败 (认证错误)` | 缺少 username/password 配置 | 在 discovery 节点添加 username 和 password |
|
||||
| `HikariPoolMXBean NullPointerException` | 定时任务执行时连接池未初始化 | 添加 poolMXBean 空值检查 |
|
||||
| `响应头缺失X-Trace-Id/X-Span-Id` | ContextInterceptor未设置响应头 | 在preHandle中调用response.setHeader() |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user