如何使用 Spring Boot 和嵌入式 Tomcat 配置此属性?

Posted

技术标签:

【中文标题】如何使用 Spring Boot 和嵌入式 Tomcat 配置此属性?【英文标题】:How do I configure this property with Spring Boot and an embedded Tomcat? 【发布时间】:2015-10-06 07:49:32 【问题描述】:

我是在 application.properties 文件中配置诸如 connectionTimeout 之类的属性,还是在其他地方进行配置?我无法从 Google 中弄清楚这一点。

Tomcat properties list

我找到了这个 Spring-Boot example,但它不包含 connectionTimeout 属性,当我在 application.properties 文件中设置 server.tomcat.connectionTimeout=60000 时出现错误。

【问题讨论】:

"org.springframework.beans.factory.BeanCreationException: 创建名为 'tomcatEbeddedServletContainerFactory' 的 bean 时出错... bean 属性 'connectionTimeout' 不可写或设置方法无效" 【参考方案1】:

在 spring boot 2.x 及更高版本之后, 嵌入tomcat的实现方法已更改。

参考下面的代码。

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(
                "####################################################################################");

        );
    

【讨论】:

【参考方案2】:

我更喜欢在服务器启动之前设置系统属性:

/**
 * 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);
    

【讨论】:

这个解决方案非常适合我:gist.github.com/vishwaraja/24f2935cad4b59ca2e85dc08368e120f 对于server.tomcat.max-threads200 是否太高?它应该更低 - 2 位数字,如 50 或类似的东西?我试图了解max-threads 的好数字是什么【参考方案3】:

Spring Boot 1.4 及更高版本

从 Spring Boot 1.4 开始,您可以使用属性 server.connection-timeout。请参阅 Spring Boot 的 common application properties。

Spring Boot 1.3 及更早版本

提供一个定制的EmbeddedServletContainerFactory bean:

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

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

    // configure some more properties

    return factory;

如果您不使用 Java 8 或不想使用 Lambda Expressions,请像这样添加 TomcatConnectorCustomizer

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

setConnectionTimeout() 方法需要以毫秒为单位的超时(请参阅 Apache Tomcat 8 Configuration Reference 中的 connectionTimeout)。

【讨论】:

我不想创建新的 TomcatEmbeddedServletContainerFactory,有没有办法只更改现有配置?该方法将何去何从? 这是自定义嵌入式 Tomcat 的documented(仅据我所知)方式。 Spring Boot 会识别你的 bean,并且不会尝试创建它自己的。 你给出的代码中的“连接器->”部分是什么? 我喜欢这个解决方案 hzpz,但我有一个问题。我只在开发模式下使用嵌入式tomcat。在生产模式下,我使用了一个外部 tomcat,它的连接器属性 connectionTimeout 设置为一分钟。如果我将您的代码添加到我的构建中,它会中断,因为我需要排除 Tomcat 嵌入式 jar。否则,我将在我的战争中依赖 Tomcat-embed.jar,并且当我部署到生产环境时,它将与外部 Tomcat 的 jars 发生冲突。我只是卡住了吗? 我不完全确定它是否有效,但你可以尝试像 Spring Boot 一样做:用 @ConditionalOnClass( Servlet.class, Tomcat.class ) 注释产生 EmbeddedServletContainerFactory bean 的 @Configuration 类。见EmbeddedServletContainerAutoConfiguration。【参考方案4】:

实际上应该是您的application.properties 中的server.connection-timeout。 Reference,建议你收藏一下。

【讨论】:

在使用server.connection-timeout属性时,需要指定单位,否则不接受。所以你可以说server.connection-timeout=5000msserver.connection-timeout=5s,两者都会给你5 秒的超时时间。但你不能只说server.connection-timeout=5000 那行不通。

以上是关于如何使用 Spring Boot 和嵌入式 Tomcat 配置此属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Spring Boot 应用程序配置嵌入式 Tomcat 虚拟主机?

如何避免使用 Spring-Boot 下载嵌入式 MongoDb

NoSuchBeanDefinitionException:PlatformTransactionManager 在 Spring Boot 2.0.0.M6 中运行 Junit 测试

如何使用 Spring Boot 和嵌入式 Tomcat 配置此属性?

如何使用Spring Boot和嵌入式Tomcat配置此属性?

如何使用 Spring Boot 配置嵌入式 ActiveMQ 代理 URL