The current Tomcat configuration properties (server.tomcat.threads.min-spare
, server.tomcat.max-connections
, etc.) apply to both the main application and the actuator.
Depending on your specific configuration this can lead to some waste, for example, you can end up with many threads in the actuator which are unnecessary (even if idle). Would it make sense to allow configuring them individually via properties? Or is this a use case for programmatic configuration?
I've also tried to configure the connectors programmatically with
@Component
public class TomcatConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers(new TomcatConnectorConfiguration());
}
public static class TomcatConnectorConfiguration implements TomcatConnectorCustomizer {
@Override
public void customize(Connector connector) {
// do stuff
}
}
}
however, TomcatConnectorConfiguration.customize()
is not being called for the actuator's connector. Perhaps the actuator is not using another connector?
Comment From: wilkinsona
Thanks for the suggestion. This is a duplicate of #9560. You can use a WebServerFactoryCustomizer
but it needs to be defined as a bean in a @ManagementContextConfiguration
. Please see https://github.com/spring-projects/spring-boot/issues/14302#issuecomment-418712080 for an example.
Comment From: joca-bt
I followed something similar to the example and now my customizer is applied to the actuator, but also to the main application. Is that expected? (I was expecting it to apply only to the actuator.)
Comment From: wilkinsona
No, a customiser declared in a @ManagementContextConfiguration
should only be applied to the separate management context. Perhaps you've placed it in a package where it's also being picked up by component scanning?
Comment From: joca-bt
Probably. I'm not customizing anything related to component scanning, just using the plain @SpringBootApplication
annotation.
This is my @ManagementContextConfiguration
class:
@ManagementContextConfiguration
public class ActuatorWebMvcConfiguration {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatConfiguration() {
return new TomcatConfiguration();
}
private static class TomcatConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers(new TomcatConnectorConfiguration());
}
}
private static class TomcatConnectorConfiguration implements TomcatConnectorCustomizer {
@Override
public void customize(Connector connector) {
// do stuff
}
}
}
spring.factories
:
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration = <packages>.ActuatorWebMvcConfiguration
Directory structure is something like:
<main-package>.<class with @SpringBootApplication>
<main-package>.<some-other-package>.ActuatorWebMvcConfiguration
Comment From: wilkinsona
Yep, that's the problem then. @SpringBootApplication
in <main-package>
will cause everything in <main-package>
and all sub-packages to be component scanned. You should move ActuatorWebMvcConfiguration
into a package that isn't the same as or a sub-package of the package that contains your main application class.