我正在尝试通过长时间运行的工作从@RestController获取StreamingResponseBody。无论我尝试哪种配置,它都会在30秒后超时。
这是在Spring Boot 2.0.3中。 我使用了下面的测试,该测试显示了相同的行为来尝试正确配置。
@RestController
public class TestController {
@RequestMapping("/streamtest")
public StreamingResponseBody handleRequest () {
return new StreamingResponseBody() {
@Override
public void writeTo (OutputStream out) throws IOException {
for (int i = 0; i < 100000; i++) {
out.write((Integer.toString(i) + " - ").getBytes());
out.flush();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
}
我尝试了此处定义的async.request-timeout设置; Async timeout downloading a large file using StreamingResponseBody on Spring Boot
我尝试覆盖WebMvcConfig设置超时。永远不会调用此方法。
@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(3600000);
WebMvcConfigurer.super.configureAsyncSupport(configurer);
}
}
我尝试定义ThreadPoolTaskExecutor:
@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return new ThreadPoolTaskExecutor();
}
}
它总是在30秒后超时并显示日志;
12:14:28.028 [http-nio-8080-exec-2] DEBUG c.b.b.bof_static.config.BofStaticExceptionHandler - Async timeout for GET [/streamtest]
12:14:28.028 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
12:14:28.028 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
12:14:28.030 [http-nio-8080-exec-2] DEBUG o.s.security.web.access.ExceptionTranslationFilter - Chain processed normally
我找不到其他解决方案。谁能指出缺少的东西吗?
答案 0 :(得分:0)
我已经在计算机上设置了一个Spring Boot项目,其配置类如下所示,
@Configuration
@EnableWebMvc
@EnableTransactionManagement
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
...
}
我只是将@EnableAsync
添加到它的下面,并在覆盖方法
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@EnableAsync
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
...
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(3600000);
}
}
我只是将您的方法带到了我的一个控制器类,然后大摇大摆地击中了它。我几分钟都没看到问题。 当我在没有对配置进行以上更改的情况下放置您的方法时,我会得到
2018-10-24 11:35:55.085 ERROR 78852 --- [nio-8080-exec-6] c.h.a.a.aop.MyExceptionHandler : Async timeout for GET [/test/common/streamtest]
所以对我来说一切似乎都很好。
我对您代码的唯一猜测是,您可能将@EnableAsync
放在了错误的位置。
此外,请尽量减少操作,现在不要尝试使用ThreadPoolTaskExecutor()
,并使用默认值SimpleAsyncTaskExecutor
执行请求。一旦让异步处理自定义超时,您就可以在以后插入它。
我正在嵌入式Tomcat中运行应用程序。
答案 1 :(得分:0)
在application.properties中设置以下选项可以解决此问题:
spring.mvc.async.request-timeout=-1
但是,如果您在代码中的任何地方实现WebMvcConfigurer
,则上述选项将被忽略,因此必须将其设置为以下内容:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
// other config...
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(-1);
}
}
您也可以将其设置为正整数(毫秒)。值-1将完全消除超时。
答案 2 :(得分:0)
打开application.properties添加以下行
# in milliseconds
spring.mvc.async.request-timeout=5000
如果这是生产代码,请不要将其值设置为-1。在大量请求的情况下,这可能导致资源匮乏。因为客户端永远不会超时,并且会保留他们正在使用的资源(线程)。