偶发问题:DevTools仅显示1次网络调用,但REST服务被多次触发
可能原因及排查方案
1. 数据库或持久层的自动重试
- PostgreSQL内置重试:当查询遇到锁等待、连接瞬断等情况时,PostgreSQL可能会自动重试执行同一查询,此时服务端会产生多线程执行日志,但客户端仅发起一次请求。可以通过查询
pg_stat_activity视图,查看是否有同一查询的多个活跃进程。 - 持久层框架重试配置:如果使用了MyBatis、Spring Data JPA或Spring Retry,可能存在你未注意到的全局重试配置或切面逻辑,触发了查询的自动重试。临时禁用重试机制,观察日志是否恢复正常。
2. Spring Boot请求处理的隐性重复
- Filter链的重复处理:虽然你的自定义Filter仅标注
@Component,但Spring Boot自动配置的Filter(如Spring Security、Actuator相关Filter)可能导致请求被二次处理。建议在Filter中打印request.getRequestURI()和Thread.currentThread().getId(),确认是否是同一请求被多个线程处理。 - 异步请求配置问题:如果Controller方法标注了
@Async,或全局配置了异步线程池,可能导致同一请求的业务逻辑被多线程并行执行。检查Controller是否有异步注解,以及application.properties中的spring.task.execution相关配置。
3. 日志打印的误导性
如果日志未添加请求追踪ID,可能会把不同请求的相同方法调用误认为是同一请求的多线程执行。建议在Filter中生成唯一UUID并放入MDC,日志格式中加入该追踪ID,即可准确区分是否为同一请求的日志。
4. Angular端的隐性重复触发(低概率)
虽然你确认UI阻塞、无多订阅,但仍可排查:
- 检查自定义HTTP拦截器是否存在重复调用
next.handle(req)的逻辑; - 确认触发请求的按钮是否在请求未完成前未设置
disabled状态,导致用户快速点击触发重复请求(虽网络面板显示1条,但可能存在请求合并或浏览器拦截?可进一步排查)。
快速排查步骤
- 给所有请求添加唯一追踪ID,明确日志归属;
- 开启PostgreSQL的查询日志,验证是否真的有重复查询执行;
- 临时禁用持久层的重试机制,观察多线程日志是否消失;
- 检查Spring Boot异步配置,确认是否存在异步执行逻辑。
内容的提问来源于stack exchange,提问作者ADKL
相关产品推荐
相关产品推荐

