Spring Boot external Tomcat not asynchronous

Viewed 975

When invoking a Callable method via ajax running on a Spring Boot application, the embedded tomcat is handling requests asynchronously and perfectly fine:

2017-07-02 09:12:24.283  INFO 3582 --- [nio-8090-exec-3] c.r.web.controllers.MainController       : Ali was stored in redis
2017-07-02 09:12:25.671  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali is searching for a chat
2017-07-02 09:12:25.820  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali last activity date was updated in redis
2017-07-02 09:12:26.053  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali retrieving random conv null
2017-07-02 09:12:26.054  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali created my own conversation
2017-07-02 09:12:26.211  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali searching...
2017-07-02 09:12:27.927  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali searching...
2017-07-02 09:12:29.128  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali searching...
2017-07-02 09:12:29.305  INFO 3582 --- [nio-8090-exec-2] c.r.web.controllers.MainController       : Zeina was stored in redis
2017-07-02 09:12:29.984  INFO 3582 --- [ngAsyncThread-2] c.r.web.controllers.MainController       : Zeina is searching for a chat
2017-07-02 09:12:30.135  INFO 3582 --- [ngAsyncThread-2] c.r.web.controllers.MainController       : Zeina last activity date was updated in redis
2017-07-02 09:12:30.285  INFO 3582 --- [ngAsyncThread-2] c.r.web.controllers.MainController       : Zeina retrieving random conv Conversation [id=bbb17857-9049-4, person1=Person [id=9a243d57-2f0c-4, name=Ali, age=22, gender=M, ip=0:0:0:0:0:0:0:1, loginDate=Sun Jul 02 09:12:23 EEST 2017, lastActiveDate=Sun Jul 02 09:12:25 EEST 2017], person2=null, creationDate=Sun Jul 02 09:12:26 EEST 2017]
2017-07-02 09:12:30.687  INFO 3582 --- [ngAsyncThread-1] c.r.web.controllers.MainController       : Ali searching...
2017-07-02 09:39:54.420  INFO 3582 --- [ngAsyncThread-3] c.r.web.controllers.MainController       : Zeina is searching for a chat

However, when I deploy the application on an external tomcat server, one call is hanging the server and the next one is only processed after the completion of the first call.

2017-07-02 06:47:57.285  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:47:58.297  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:47:59.309  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:48:00.323  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:48:01.335  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:48:02.347  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:48:03.359  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun searching...
2017-07-02 06:48:04.388  INFO 3324 --- [SpringAsyncThread-4] c.r.web.controllers.MainController       : Zanzoun remove dead conversatio
2017-07-02 06:48:04.682  INFO 3324 --- [SpringAsyncThread-5] c.r.web.controllers.MainController       : AJ is searching for a chat
2017-07-02 06:48:04.695  INFO 3324 --- [SpringAsyncThread-5] c.r.web.controllers.MainController       : AJ last activity date was updated in redis
2017-07-02 06:48:04.708  INFO 3324 --- [SpringAsyncThread-5] c.r.web.controllers.MainController       : AJ retrieving random conv Conversation [id=f5fe39ac-91ce-4, person1=Person [id=e25d18f3-9729-4, name=Zanzoun, age=12, gender=F, ip=91.197.46.40, loginDate=Sun Jul 02 06:47:32 UTC 2017, lastActiveDate=Sun Jul 02 06:47:48 UTC 2017], person2=null, creationDate=Sun Jul 02 06:47:48 UTC 2017]
2017-07-02 06:48:50.833  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ is searching for a chat
2017-07-02 06:48:50.845  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ last activity date was updated in redis
2017-07-02 06:48:50.860  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ retrieving random conv null
2017-07-02 06:48:50.860  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ created my own conversation
2017-07-02 06:48:50.872  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ searching...
2017-07-02 06:48:51.884  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ searching...
2017-07-02 06:48:52.896  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ searching...
2017-07-02 06:48:53.908  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ searching...
2017-07-02 06:48:54.921  INFO 3324 --- [SpringAsyncThread-6] c.r.web.controllers.MainController       : AJ searching...

In the above log, the call from Zanzoun and AJ were sent at the same time, however AJ processing didn't start until Zanzoun was over.

Below I list my configurations:

@Configuration
@EnableAsync
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("main");
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/admin").setViewName("admin");
    }

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(asyncTaskExecutor());
    }

    @Bean
    public AsyncTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(200);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("SpringAsyncThread-");
        executor.initialize();
        return executor;
    }
}

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class App extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(App.class);
    }
}

Update 1

I applied the answer provided in the comments by @divine , however the problem was not solved:

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" 
               minProcessors="3"
               maxProcessors="8"
               maxThreads="20"
               connectionTimeout="150000" 
               asyncTimeout="150000" />

Update 2

I have tested locally on my Linux machine using an external Tomcat 8.0.21 and it works perfectly. However, I installed also the same version of Tomcat in Windows (It's actually an AWS instance), and the problem remains the same, so it's an OS/Version issue?

Update 3

Here's the pom file as requested:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.randomni</groupId>
    <artifactId>web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <!-- Define that this project is a child of the spring-boot-starter-parent 
        project which contains all default maven configuration, this project inherits 
        all these configurations -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
    </parent>

    <dependencies>
        <!-- Main Web Dependency, contains MVC and Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mobile</artifactId>
        </dependency>
        <!-- Spring MVC with Thymeleaf views -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- WebJars -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>normalize.css</artifactId>
            <version>5.0.0</version>
        </dependency>
        <!-- For Deployment -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
        <!-- Default Thymeleaf of Spring Boot is version 2, so we had to add these -->
        <thymeleaf.version>3.0.6.RELEASE</thymeleaf.version>
        <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
    </properties>

</project>
1 Answers
Related