1. CompletableFuture 与自定义 Executor 组合时,链路追踪上下文丢失会导致什么问题,包装 Runnable 的方案如何保证清理
CompletableFuture 与自定义 Executor 组合时,链路追踪上下文丢失会导致什么问题?包装 Runnable 的方案如何保证清理?
- 上下文丢失
- 链路追踪
- 包装 Runnable + 清理
CompletableFuture 用自定义 Executor 执行任务时,任务在 Executor 线程池中运行,ThreadLocal 类上下文(如 TraceId、MDC)不会自动从调用线程传递到执行线程,导致链路追踪断链、日志无法关联。包装 Runnable 方案:用包装器在任务执行前从提交线程捕获上下文、设置到执行线程,执行后清理(remove 防止泄漏)。关键是保证清理:在 finally 中清除 ThreadLocal,否则线程池复用导致上下文泄漏到其他任务。可用 TransmittableThreadLocal 或手写包装器。
上下文丢失是异步/线程池的常见问题。包装 Runnable 需"捕获-设置-清理"三步,清理尤其重要。
Runnable wrap(Runnable task, Map<String, String> ctx) {
return () -> {
MDC.setContextMap(ctx);
try { task.run(); } finally { MDC.clear(); }
};
}