【问题标题】:Share embedded Tomcat executor between multiple connectors in Spring Boot在 Spring Boot 中的多个连接器之间共享嵌入式 Tomcat 执行器
【发布时间】:2018-06-25 11:25:00
【问题描述】:

我正在尝试使用带有两个连接器(一个 HTTP 和一个 HTTPS)和一个共享执行器的 Spring Boot 设置一个嵌入式 Tomcat。

我已经在 Spring Boot application.properties 上配置了 HTTPS 连接器,然后按照documentation 中的描述以编程方式添加了 HTTP 连接器。

但是,我没有看到任何选项可以为两个连接器使用相同的 Executor。我想将这种设置翻译成 Spring Boot 的配置:

<Executor name="tomcatSharedThreadPool" namePrefix="catalina-exec-" 
    maxThreads="150" minSpareThreads="4"/>

<Connector executor="tomcatSharedThreadPool"
           port="80" protocol="HTTP/1.1" 
           connectionTimeout="20000" 
           redirectPort="443" />
<Connector executor="tomcatSharedThreadPool"
           port="443" protocol="HTTP/1.1" 
           connectionTimeout="20000" />

有人知道怎么做吗?

谢谢。

【问题讨论】:

标签: tomcat spring-boot


【解决方案1】:

考虑一下我博客文章中的这个改编的 sn-p:Configuring Tomcat to Listen on Multiple ports using Spring Boot

@Configuration
public class EmbeddedTomcatConfiguration {

    @Value("${server.port}")
    private String serverPort;

    @Value("${management.port:${server.port}}")
    private String managementPort;

    @Value("${server.additionalPorts:null}")
    private String additionalPorts;

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        Connector[] additionalConnectors = this.additionalConnector();
        if (additionalConnectors != null && additionalConnectors.length > 0) {
            tomcat.addAdditionalTomcatConnectors(additionalConnectors);
        }
        return tomcat;
    }

    private Connector[] additionalConnector() {
        if (StringUtils.isBlank(this.additionalPorts)) {
            return null;
        }
        Set<String> defaultPorts = Sets.newHashSet(this.serverPort, this.managementPort);
        String[] ports = this.additionalPorts.split(",");
        List<Connector> result = new ArrayList<>();
        for (String port : ports) {
            if (!defaultPorts.contains(port)) {
                Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
                connector.setScheme("http");
                connector.setPort(Integer.valueOf(port));
                result.add(connector);
            }
        }
        return result.toArray(new Connector[] {});
    }
}

到目前为止还没有设置执行器,请随意测试在tomcat.addAdditionalTomcatConnectors(additionalConnectors);之后添加这些行:

tomcat.addConnectorCustomizers(new TomcatConnectorCustomizer() {

                @Override
                public void customize(Connector connector) {
                    ProtocolHandler handler = connector.getProtocolHandler();
                    if (handler instanceof AbstractProtocol) {
                        AbstractProtocol<?> protocol = (AbstractProtocol<?>) handler;
                        protocol.setExecutor(<your executor bean>);
                    }
                }
            });

【讨论】:

  • 感谢您的帮助,我刚刚完成了您的回答。
  • 如果您认为我的回答可以帮助您回答您的问题,您会考虑将其标记为“答案”吗?谢谢
【解决方案2】:

为了让 Tomcat 管理 executor,您必须将自定义的 executor 添加到 Tomcat 服务中,以便将其集成到 Tomcat 生命周期中。

为此,请使用TomcatEmbeddedServletContainerFactory 的方法addConnectorCustomizers。然后,在连接器定制器中,您可以访问 Tomcat 服务,以便将您的自定义执行器添加到 Tomcat 生命周期并设置到每个连接器。

public class MultipleConnectorCustomizer implements TomcatConnectorCustomizer {
@Override
public void customize(final Connector pConnector) {
    // Create shared Tomcat executor
    Service tomcatService = pConnector.getService();
    StandardThreadExecutor executor = createExecutor();
    tomcatService.addExecutor(executor);

    // Customize default connector (HTTPS created by the TomcatEmbeddedServletContainerFactory)
    ProtocolHandler handler = pConnector.getProtocolHandler();
    if (handler instanceof AbstractProtocol) {
        AbstractProtocol<?> protocol = (AbstractProtocol<?>) handler;
        protocol.setExecutor(executor);
    }

    // Create additional redirected HTTP connector
    Connector additionalConnector = new Connector(fTomcatProperties.getProtocol().getProtocol());
    additionalConnector.setPort(fTomcatProperties.getHttpRedirectedPort().intValue());
    additionalConnector.setRedirectPort(fServerProperties.getPort().intValue());
    ProtocolHandler additionalHandler = additionalConnector.getProtocolHandler();
    if (additionalHandler instanceof AbstractProtocol) {
        AbstractProtocol<?> protocol = (AbstractProtocol<?>) additionalHandler;
        protocol.setExecutor(executor);
    }

    tomcatService.addConnector(additionalConnector);
}

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2015-03-18
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 2019-12-13
    相关资源
    最近更新 更多