在 Spring Boot 中的多个连接器之间共享嵌入式 Tomcat 执行器
Posted
技术标签:
【中文标题】在 Spring Boot 中的多个连接器之间共享嵌入式 Tomcat 执行器【英文标题】:Share embedded Tomcat executor between multiple connectors in Spring Boot 【发布时间】: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" />
有人知道怎么做吗?
谢谢。
【问题讨论】:
尽管这个问题比较老,但有一个重复的标题更好=更容易找到... Configure Spring Boot with two ports的可能重复 【参考方案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);
【讨论】:
以上是关于在 Spring Boot 中的多个连接器之间共享嵌入式 Tomcat 执行器的主要内容,如果未能解决你的问题,请参考以下文章
最佳实践——在应用之间共享 Spring-boot Service 和 Repo 层代码
SPring Boot Services 之间的共享配置(在 git 上)