问题描述
- 使用Spring boot 时,如果打开了management 端口,则tomcat 会启动两个线程池,分别处理来自两个端口的请求
- 通常我们会使用
server.tomcat.threads 自定义线程池大小,以满足业务的处理需求;而此时management 会复用此配置,配置management的线程池大小
- 通常management 是管理端口,请求量极少,线程需求少;而server.port 的业务端口因承载业务请求,线程需求大,此时共享同一个配置会造成线程池资源的浪费
解决方式
- SpringBoot 在初始化management 的context 时,不会扫描项目中的自定义Configuration或者ManagementContextConfiguration 定义的class,导致其线程池无法自定义
- 可以在META-INFO/spring.factories文件中配置org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=xxx 的方式自定义配置类
- 此配置类需要通过jar包依赖的方式加入到项目中,spring boot 启动时会自动扫描该文件,并加载其定义的class
class
@ManagementContextConfiguration
public class TomcatManagementCustomizerConfiguration {
private static final Log log = LogFactory.getLog(TomcatManagementCustomizerConfiguration.class);
@Bean
ManagementWebServerFactoryCustomizer<ConfigurableServletWebServerFactory> servletManagementWebServerFactoryCustomizer(
@Value("${management.server.threads.min-spare:5}") int managementMinSpareThreads,
@Value("${management.server.threads.max-threads:5}") int managementMaxThreads,
@Value("${management.server.accept-count:5}") int managementAcceptCount,
ListableBeanFactory beanFactory) {
log.info("TomcatManagementCustomizerConfiguration init..");
if (managementMinSpareThreads > managementMaxThreads) {
managementMinSpareThreads = managementMaxThreads;
}
return new TomcatManagementCustomizer(beanFactory, managementMinSpareThreads, managementMaxThreads, managementAcceptCount);
}
static class TomcatManagementCustomizer extends ManagementWebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
private final int managementMinSpareThreads;
private final int managementMaxThreads;
private final int managementAcceptCount;
protected TomcatManagementCustomizer(ListableBeanFactory beanFactory, int managementMinSpareThreads
, int managementMaxThreads, int managementAcceptCount) {
super(beanFactory, TomcatWebServerFactoryCustomizer.class);
this.managementMinSpareThreads = managementMinSpareThreads;
this.managementMaxThreads = managementMaxThreads;
this.managementAcceptCount = managementAcceptCount;
}
@Override
@SuppressWarnings("rawtypes")
protected void customize(ConfigurableServletWebServerFactory factory, ManagementServerProperties managementServerProperties, ServerProperties serverProperties) {
super.customize(factory, managementServerProperties, serverProperties);
((TomcatServletWebServerFactory) factory).addConnectorCustomizers((connector) -> {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractProtocol) {
AbstractProtocol protocol = (AbstractProtocol) handler;
protocol.setMinSpareThreads(managementMinSpareThreads);
protocol.setMaxThreads(managementMaxThreads);
protocol.setAcceptCount(managementAcceptCount);
log.info("TomcatManagementCustomizerConfiguration custom for port:" + protocol.getPort() + ", managementMinSpareThreads:" + managementMinSpareThreads
+ ", managementMaxThreads:" + managementMaxThreads + ", managementAcceptCount:" + managementAcceptCount);
}
});
}
}
}