Set async processing timeout on Tomcat 8.5 / Sprin

2019-08-08 21:56发布

问题:

I deploy a Spring MVC webapp on Tomcat 8.5 with the following controller:

import java.util.concurrent.Callable;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class AppController {

    @RequestMapping(value="getOkSync", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody String getOkSync() {

        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return "ok";
    }

    @RequestMapping(value="getOkAsync", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody Callable<String> getOkAsync() {

        return new Callable<String>() {
            @Override
            public String call()  {
                try {
                    Thread.sleep(60000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                return "ok";
            }
        };
    }

}

while the first method returns after 60 sec the correct result, the second method returns after approximately 30 seconds with HTTP response code 500 and the corresponding Spring class logs

Could not complete async processing due to timeout or network error.

(if the delay is set on the other hand to 20 seconds both metods return "ok" after 20 seconds as expected).
Is the timeout controlled by Spring MVC or by Tomcat? What is the property which controls the timeout?

回答1:

Well, the following works (i.e. both methods return now "ok" after 60 seconds), though there is an interaction between Spring and Tomcat which I do not understand completely at the moment (in any case it appears that if I don't set the property via Spring, the timeout will be that of Tomcat, though I don't know how to set the latter)

@Configuration
@EnableWebMvc
@ComponentScan(basePackages="my.base.package")
public class AppConfig extends WebMvcConfigurerAdapter implements WebApplicationInitializer {

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        // TODO Auto-generated method stub
        configurer.setDefaultTimeout(120000);
        super.configureAsyncSupport(configurer);
    }

    ...