一句话总结:
多AOP+TraceId解决快速定位bug,注意切面的顺序问题和性能的问题呀
业务痛点与需求
在投行交易系统和对公贷款风控计算场景中,高并发、低延迟和敏感数据安全是核心诉求。在现有设计下,存在以下痛点:
- 问题定位困难 :日均百万级交易请求下,日志分散且缺乏唯一标识,无法快速关联全链路操作。
- 合规性要求严格 : 用户身份证、交易金额等敏感字段需脱敏
核心需求:
- 生成唯一traceId贯穿全链路
- 敏感字段自动脱敏,降低代码侵入性
- 高并发下性能损耗可控
架构设计
核心实现难点
1. 多AOP切面顺序控制
@Order(1) // 优先级:脱敏切面 > 日志切面
public class DesensitizationAspect {
@Around("execution(* com..controller.*(..))")
public Object doAround(ProceedingJoinPoint pjp) {
// 反射脱敏实现
}
}
@Order(2)
public class LoggingAspect {
@Around("execution(* com.chloe..*Controller.*(..))")
public Object around(JoinPoint joinPoint) {
// 日志记录,如果存在脱敏的annotation,对注解字段进行脱敏
}
}
2. ThreadLocal穿透问题
- 问题:异步任务/线程池复用导致traceId丢失
- 方案:使用TransmittableThreadLocal(TTL)
public class TraceContext {
private static final ThreadLocal<String> context =
new TransmittableThreadLocal<>(); // 支持线程池穿透
public static void setTraceId(String traceId) {
context.set(traceId);
}
public static String getTraceId() {
return context.get();
}
}
最终效果
- 日志查询效率提升10倍 :通过traceId可在ELK中秒级定位全链路日志
- 脱敏代码量减少90% : 新增敏感字段只需添加注解,无需修改业务逻辑
- 压测指标 :单节点QPS 1.2万时,平均耗时增加<5ms
后续优化方向(还没试过!)
- 分布式追踪
- 动态脱敏:根据用户角色返回不同脱敏级别
- 异步写入+分级存储,降低磁盘IO压力