在Spring Boot中的多个连接器之间共享嵌入式Tomcat执行器

时间:2018-01-16 17:16:38

标签: tomcat spring-boot

我正在尝试使用Spring Boot设置嵌入式Tomcat,其中包含两个连接器(HTTP和HTTPS)以及两者的共享执行程序。

我在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" />

任何人都知道这样做的方法吗?

感谢。

2 个答案:

答案 0 :(得分:2)

从我的博文中考虑这个改编的片段: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>);
                    }
                }
            });

答案 1 :(得分:0)

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

要实现此目的,请使用addConnectorCustomizers的方法TomcatEmbeddedServletContainerFactory。然后,在连接器定制程序中,您可以访问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);
}