13

Do I configure properties like the connectionTimeout in the application.properties file or is the somewhere else to do it? I can't figure this out from Google.

Tomcat properties list

I found this Spring-Boot example, but it does not include a connectionTimeout property and when I set server.tomcat.connectionTimeout=60000 in my application.properties file I get an error.

smuggledPancakes
  • 9,881
  • 20
  • 74
  • 113
  • "org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatEbeddedServletContainerFactory'... Bean property 'connectionTimeout' is not writable or has an invalid setter method" – smuggledPancakes Jul 16 '15 at 18:21

4 Answers4

28

Spring Boot 1.4 and later

As of Spring Boot 1.4 you can use the property server.connection-timeout. See Spring Boot's common application properties.

Spring Boot 1.3 and earlier

Provide a customized EmbeddedServletContainerFactory bean:

@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();

    factory.addConnectorCustomizers(connector -> 
            ((AbstractProtocol) connector.getProtocolHandler()).setConnectionTimeout(10000));

    // configure some more properties

    return factory;
}

If you are not using Java 8 or don't want to use Lambda Expressions, add the TomcatConnectorCustomizer like this:

    factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
        @Override
        public void customize(Connector connector) {
            ((AbstractProtocol) connector.getProtocolHandler()).setConnectionTimeout(10000);
        }
    });

The setConnectionTimeout() method expects the timeout in milliseconds (see connectionTimeout in Apache Tomcat 8 Configuration Reference).

hzpz
  • 7,536
  • 1
  • 38
  • 44
  • I do not want to create a new TomcatEmbeddedServletContainerFactory, is there a way to just change the existing configuration? Where would that method go? – smuggledPancakes Jul 16 '15 at 18:44
  • This is the [documented](http://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-configure-tomcat) (and to my knowledge only) way to customize the embedded Tomcat. Spring Boot will recognize your bean and won't try to create its own. – hzpz Jul 16 '15 at 18:48
  • what is the "connector ->" part of the code you gave? – smuggledPancakes Jul 16 '15 at 18:59
  • I like this solution hzpz, but I have an issue. I only use the embedded tomcat in development mode. In production mode, I use an external tomcat, which has the connector property, connectionTimeout, set to a minute. If I add your code to my build, it breaks because I need to exclude the Tomcat embedded jars. Otherwise I will have a dependency on Tomcat-embed.jar in my war and that will fight with external Tomcat's jars when I deploy to production. Am I just stuck? – smuggledPancakes Jul 16 '15 at 21:42
  • 1
    I'm not entirely sure if it works, but you could try to do the same as Spring Boot does: annotate the `@Configuration` class that produces the `EmbeddedServletContainerFactory` bean with `@ConditionalOnClass({ Servlet.class, Tomcat.class })`. See [EmbeddedServletContainerAutoConfiguration](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration.java). – hzpz Jul 17 '15 at 05:12
  • Did the @ConditionalOnClass approach work? If so, I will add it to my answer for future reference. – hzpz Jul 17 '15 at 15:50
  • I actually did not go down the route of using @ConditionalOnClass. I am excluding the TomcatConfiguration class from my WAR and the tomcat-embed.jar from my WAR too. I am hoping this works. I am in the process of testing, but I will update you if anything changes. – smuggledPancakes Jul 17 '15 at 15:53
  • It looked like the @ConditionalOnClass({ Servlet.class, Tomcat.class }) worked for my WAR. I was accidentally including my Tomcat configuration class, which had dependencies on on class in tomcat-embed, yet my deployed WAR didn't crash when I ran it. I fixed my ant file to exclude Tomcat configuration class, I don't want it in the WAR at all. – smuggledPancakes Jul 17 '15 at 19:12
  • Thanks for the update! I will test @ConditionalOnClass myself some time. Let's keep it in the comments for now. – hzpz Jul 17 '15 at 22:50
  • I have almost the same question, but for setting [maxSwallowSize](http://tomcat.apache.org/tomcat-8.0-doc/config/http.html#Standard_Implementation) on the connector (introduced in Tomcat 8.0.9 I think). I can't find the class that contains that yet. Any ideas? (I'll open a new question if it's too different of a property) – Jim Aug 11 '15 at 22:11
  • Of course, minutes after I type this, I figured it out, I think. ((AbstractHttp11Protocol) connector.getProtocolHandler()).setMaxSwallowSize(-1) . We'll see if that's safe to do, but it appears to be. – Jim Aug 11 '15 at 22:29
  • Does the time out in seconds or milliseconds. The API doc does not provide any info? – Harshana Mar 15 '16 at 13:36
  • thanks. well i have tried above in my sample spring boot project but it did not work. would you pls hav a look on below question, http://stackoverflow.com/questions/36076737/springboot-tomcatembeddedservletcontainer-keepalivetimeout-not-working – Harshana Mar 19 '16 at 03:32
4

I prefer set of system properties before the server start:

/**
 * Start SpringBoot server
 */
@SpringBootApplication(scanBasePackages= {"com.your.conf.package"})
//@ComponentScan(basePackages = "com.your.conf.package")
public class Application {
    public static void main(String[] args) throws Exception {
        System.setProperty("server.port","8132"));
        System.setProperty("server.tomcat.max-threads","200");
        System.setProperty("server.connection-timeout","60000");
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
    }
}
subhashis
  • 4,629
  • 8
  • 37
  • 52
Juraj
  • 738
  • 2
  • 9
  • 26
  • This solution worked for me perfectly well: https://gist.github.com/vishwaraja/24f2935cad4b59ca2e85dc08368e120f – user1807948 Dec 29 '16 at 10:45
  • 1
    Is `200` too high for `server.tomcat.max-threads` ? Should it be lower - 2 digit number like `50` or something like that? I am trying to understand what is a good number for `max-threads` – SGB Sep 06 '17 at 16:24
2

After spring boot 2.x and later, the implement method of the embeding tomcat has been changed.

refer to the code below.

import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class TomcatCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Autowired
    private ContainerProperties containerProperties;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addConnectorCustomizers(connector -> {
            AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) connector.getProtocolHandler();

            protocol.setMaxKeepAliveRequests(10);


            log.info("####################################################################################");
            log.info("#");
            log.info("# TomcatCustomizer");
            log.info("#");
            log.info("# custom maxKeepAliveRequests {}", protocol.getMaxKeepAliveRequests());
            log.info("# origin keepalive timeout: {} ms", protocol.getKeepAliveTimeout());
            log.info("# keepalive timeout: {} ms", protocol.getKeepAliveTimeout());
            log.info("# connection timeout: {} ms", protocol.getConnectionTimeout());
            log.info("# max connections: {}", protocol.getMaxConnections());
            log.info("#");
            log.info(
                "####################################################################################");

        });
    }
}
장재훈
  • 621
  • 1
  • 6
  • 9
1

It's actually supposed to be server.connection-timeout in your application.properties. Reference, I suggest you bookmark it.

rorschach
  • 2,871
  • 1
  • 17
  • 20
  • 7
    When using the `server.connection-timeout` property, you need to specify units or it won't take it. So you can say `server.connection-timeout=5000ms` or `server.connection-timeout=5s`, both of which will give you a 5 second timeout. But you can't just say `server.connection-timeout=5000` That won't work. – MiguelMunoz Sep 17 '18 at 02:04