1. 一、AsyncRequestTimeoutException
1.1. controller代码。
@GetMapping("/{docName}")
public StreamingResponseBody getDocument(@PathVariable String docName) {
return documentService.findByDocName(docName);
}
1.2. Service代码。
当线程响应很慢。Thread.sleep(63000)
阻塞63秒。请求之后会出现AsyncRequestTimeoutException
异常。
@Override
public StreamingResponseBody findByDocName(String docName) {
return new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
try {
Thread.sleep(63000);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputStream.write(get(docName));
}
};
}
1.3. 异常如下:
出现异常的原因是StreamingResponseBody
响应太慢。
org.springframework.web.context.request.async.AsyncRequestTimeoutException: null
at org.springframework.web.context.request.async.TimeoutCallableProcessingInterceptor.handleTimeout(TimeoutCallableProcessingInterceptor.java:44)
at org.springframework.web.context.request.async.CallableInterceptorChain.triggerAfterTimeout(CallableInterceptorChain.java:94)
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$1(WebAsyncManager.java:302)
at java.util.ArrayList.forEach(ArrayList.java:1257)
。。。。。。
1.4. 解决方式:
在配置文件中加入下面的参数:(如果前面有nginx转发,注意设置nginx读取后端的超时时间)
spring.mvc.async.request-timeout = 3600000
查看springboot的默认配置这个值没有默认值,默认使用底层实现。
2. 二、Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH 和 java.io.IOException: Broken pipe 。
这个错误出现的步骤。请求图片,不等服务器返回就关闭浏览器(也就是客户端不等待服务器返回,就关闭了连接。客户端有可能是nginx。),等一会就会出现这个错误。
这里是springboot官方对这个问题的描述。
这个是Tomcat9的问题,可以使用降级或升级tomcat,也可以使用jetty等其他容器替换。
java.lang.IllegalStateException: Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]
at org.apache.coyote.AsyncStateMachine.asyncError(AsyncStateMachine.java:440)
at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:512)
at org.apache.coyote.Request.action(Request.java:430)
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:341)
at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:736)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:665)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:376)