You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用中客户端请求处理时宕机,服务端如何记录该问题?

在Spring Boot应用B中记录客户端A宕机场景的可行方案

1. 捕获TCP连接异常

当A在B处理请求过程中宕机,B向A发送响应时,TCP连接通常已断开,Web服务器(Tomcat、Jetty等)会抛出对应的连接异常,比如Tomcat的ClientAbortException、Jetty的EofException。你可以通过全局异常处理器捕获这类异常,结合请求上下文记录关键信息:

  • 写一个@ControllerAdvice类,定向捕获这类客户端断开异常
  • 从HttpServletRequest里提取请求ID、客户端IP、请求路径等信息,写入日志或存储系统
  • 示例代码:
@ControllerAdvice
public class ClientAbortHandler {
    private static final Logger logger = LoggerFactory.getLogger(ClientAbortHandler.class);

    @ExceptionHandler(value = {ClientAbortException.class, EofException.class})
    public void handleClientDisconnect(Exception e, HttpServletRequest request) {
        String requestId = request.getHeader("X-Request-ID"); // 假设A请求时携带唯一请求ID
        String clientIp = request.getRemoteAddr();
        String requestPath = request.getRequestURI();
        logger.error("客户端[{}]在请求[{}](请求ID:{})处理完成后宕机,响应发送失败",
                     clientIp, requestPath, requestId, e);
    }
}

2. 自定义响应发送监听

通过Spring的扩展机制,监听响应发送的状态:

  • 实现ResponseBodyAdvice,在响应体写入前标记请求已处理完成
  • 或者包装HttpServletResponse,重写flushBuffer、sendError等方法,捕获响应发送失败的异常
  • 如果用异步请求处理,还可以通过AsyncListener监听异步上下文的完成事件,判断响应是否成功送达

3. 请求ID事后对账

如果A和B约定了统一的请求ID:

  • B在接收到请求时,记录请求ID、接收时间、处理结束时间
  • 后续通过定时任务,对比A的请求日志(若A有持久化请求记录)和B的响应日志,找出B已处理但A未收到响应的请求ID,标记为客户端宕机场景
  • 这种方式适合事后排查,无法实时感知,但能覆盖所有场景(包括TCP连接未及时断开的情况)

注意点

  • 若A宕机时TCP连接未及时断开,B可能成功发送响应但A永远无法接收,这种情况B无法实时感知,只能通过对账发现
  • 不同Web服务器抛出的异常类型不同,需要根据B实际使用的服务器(Tomcat/Jetty/Netty)调整异常捕获的类型

内容的提问来源于stack exchange,提问作者swapnil jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:12:48