并发情况下advice记录日志错乱如何解决?
问题描述
Springboot项目,在频繁调用多个接口时,advice里记录的日志会错乱。现象是这样的:在请求量大的时候,A请求正在执行未执行完毕,B请求进入并报了异常,B请求的错误日志被A记录了下来,同时A请求也莫名其妙的调用也失败了。请问如何解决?
相关代码
@Aspect
@Component
@EnableAspectJAutoProxy
public class AdviceApi {
@Autowired
private LogAnalyseService logAnalyseService;
// 记录日志的对象Bean
@Bean
public LogChannelCall getBean() {
return new LogChannelCall();
}
// 统计调用时长
private ThreadLocal<Long> startTime = new ThreadLocal<>();
@Pointcut("execution(* com.api.controller.*.*(..))")
public void pointcut() {
}
@Before("pointcut()")
public void before() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String userId = request.getParameter("userId");
String remoteAddr = request.getRemoteAddr();
logChannelCall.setUserId(userId);
logChannelCall.setIp(remoteAddr);
startTime.set(System.currentTimeMillis());
}
@After("pointcut()")
public void after() {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
boolean successful = response.getStatus() == 200;
logChannelCall.setSuccessful(successful);
}
@AfterReturning("pointcut()")
public void afterReturning() {
logChannelCall.setSuccessful(true);
logChannelCall.setResponseTime(System.currentTimeMillis() - startTime.get());
logAnalyseService.insertV3Log(logChannelCall);
}
@AfterThrowing(throwing = "ex", pointcut = "pointcut()")
public void afterThrowing(Exception ex) {
logChannelCall.setSuccessful(false);
logChannelCall.setReason(ex.getMessage());
logChannelCall.setResponseTime(System.currentTimeMillis() - startTime.get());
// 执行插入日志操作
logAnalyseService.insertV3Log(logChannelCall);
}
}
你期待的结果是什么?实际看到的错误信息又是什么?
请大家帮我分析一下,首先如何解决日志错乱的问题、其次,为何B请求错误会导致A请求也失败呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经过问题评论里的友♂ 好讨论,看来也不是个啥大难题,你需要的形参参数数组,这样应该可以达到你想要对应的效果了叭
你的日志记录对象并非线程安全对象,改为线程安全对象应该就不会出现这样的问题。