250210-记一次客户端超时断开连接问题处理

946 阅读1分钟

报错信息

org.springframework.web.context.request.async.AsyncRequestNotUsableException: ServletOutputStream failed to write: java.io.IOException: Broken pipe

原因

服务端处理请求时间超过客户端最大等待时间,客户端主动断开连接。

解决方向

1.增加客户端异步请求等待时长
2.优化服务端代码逻辑,避免超时(我这个问题是sql查询时间60s左右导致,最终优化了sql解决该问题)

增加客户端异步请求等待时长

方法一:全局配置

配置文件方式:

spring.mvc.async.request-timeout=120000

代码配置:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        // 设置全局异步请求超时时间为 5000 毫秒(5秒)
        configurer.setDefaultTimeout(5000);
    }
}

方法二:为接口单独配置超时时长

import org.springframework.web.context.request.async.WebAsyncTask;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/async-endpoint")
    public WebAsyncTask<String> asyncEndpoint() {
        // 设置超时时间为 5000 毫秒(5秒)
        long timeout = 5000;

        WebAsyncTask<String> webAsyncTask = new WebAsyncTask<>(timeout, () -> {
            // 模拟一个耗时操作
            Thread.sleep(3000); // 假设这里是一个耗时操作
            return "Async result";
        });

        // 设置超时处理逻辑
        webAsyncTask.onTimeout(() -> "Request timed out");

        return webAsyncTask;
    }
}

优化服务端代码逻辑:

方法一:减少服务端处理时间,找到耗时点,减少耗时

方法二:增加异常捕获,友好提示

try {
    // 处理请求并写入响应
} catch (IOException e) {
    // 记录日志或进行其他处理
    logger.error("IOException occurred: ", e);
}