首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@RestController与StreamingResponseBody异步请求-超时不起作用

@RestController与StreamingResponseBody异步请求-超时不起作用
EN

Stack Overflow用户
提问于 2018-10-23 19:22:10
回答 3查看 2.6K关注 0票数 2

我正在尝试从@RestController获取一个长时间运行的作业的StreamingResponseBody。无论我尝试什么配置,它都会在30秒后超时。

这是在Spring Boot 2.0.3中。我使用了下面的测试,它显示了相同的行为,以尝试并获得正确的配置。

代码语言:javascript
复制
@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来设置超时。此方法永远不会调用。

代码语言:javascript
复制
@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setDefaultTimeout(3600000);
        WebMvcConfigurer.super.configureAsyncSupport(configurer);
    }
}

我尝试过定义ThreadPoolTaskExecutor:

代码语言:javascript
复制
@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        return new ThreadPoolTaskExecutor();
    }
}

它总是在记录日志的30秒后超时;

代码语言:javascript
复制
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

我找不到任何其他的解决方案。有谁能指出遗漏了什么吗?

EN

回答 3

Stack Overflow用户

发布于 2019-08-27 17:22:33

在application.properties中设置以下选项可以解决此问题:

spring.mvc.async.request-timeout=-1

但是,如果您在代码中实现WebMvcConfigurer anywhere,则上述选项将被忽略,因此您必须将其设置为:

代码语言:javascript
复制
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    // other config...
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setDefaultTimeout(-1);
    }
}

也可以将其设置为正整数(毫秒)。值-1将完全消除超时。

票数 3
EN

Stack Overflow用户

发布于 2020-12-02 02:57:41

打开application.properties添加以下行

代码语言:javascript
复制
# in milliseconds 
spring.mvc.async.request-timeout=5000 

如果这是生产代码,请不要将其值设置为-1。在大量请求的情况下,这可能会导致资源匮乏。原因客户端永远不会超时,并将保留它们正在使用的资源(线程)。

票数 1
EN

Stack Overflow用户

发布于 2018-10-24 14:23:49

我已经在我的机器上设置了一个Spring Boot项目,其中包含如下所示的配置类,

代码语言:javascript
复制
@Configuration
@EnableWebMvc
@EnableTransactionManagement
public class MyConfiguration extends WebMvcConfigurerAdapter {
  ...
  ...
}

我只是简单地将@EnableAsync添加到它和重写的方法下面,

代码语言:javascript
复制
    @Configuration
    @EnableWebMvc
    @EnableTransactionManagement
    @EnableAsync
    public class MyConfiguration extends WebMvcConfigurerAdapter {
      ...
      ...
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
      configurer.setDefaultTimeout(3600000);
    }
   }

我只是简单地把你的方法放到我的一个控制器类中,然后从swagger中点击它。我在几分钟内看不到问题。当我把你的方法放在没有上述修改的配置中时,我确实得到了,

代码语言:javascript
复制
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(),让您的请求使用default - SimpleAsyncTaskExecutor执行。一旦你让你的异步工作与自定义超时,你可以稍后插入它。

我在嵌入式tomcat中运行应用程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52947789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档