Disable Tomcat's MBean Registry by default
Closes gh-16498
This commit is contained in:
parent
080a2f5c3b
commit
b603cd5d4b
|
|
@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.web.embedded.NettyWebServerFactory
|
||||||
import org.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer;
|
import org.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer;
|
||||||
import org.springframework.boot.autoconfigure.web.embedded.UndertowWebServerFactoryCustomizer;
|
import org.springframework.boot.autoconfigure.web.embedded.UndertowWebServerFactoryCustomizer;
|
||||||
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryCustomizer;
|
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryCustomizer;
|
||||||
|
import org.springframework.boot.autoconfigure.web.reactive.TomcatReactiveWebServerFactoryCustomizer;
|
||||||
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
|
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
@ -65,6 +66,7 @@ public class ReactiveManagementChildContextConfiguration {
|
||||||
ReactiveManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory) {
|
ReactiveManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory) {
|
||||||
super(beanFactory, ReactiveWebServerFactoryCustomizer.class,
|
super(beanFactory, ReactiveWebServerFactoryCustomizer.class,
|
||||||
TomcatWebServerFactoryCustomizer.class,
|
TomcatWebServerFactoryCustomizer.class,
|
||||||
|
TomcatReactiveWebServerFactoryCustomizer.class,
|
||||||
JettyWebServerFactoryCustomizer.class,
|
JettyWebServerFactoryCustomizer.class,
|
||||||
UndertowWebServerFactoryCustomizer.class,
|
UndertowWebServerFactoryCustomizer.class,
|
||||||
NettyWebServerFactoryCustomizer.class);
|
NettyWebServerFactoryCustomizer.class);
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,12 @@
|
||||||
package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat;
|
package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import io.micrometer.core.instrument.MeterRegistry;
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics;
|
import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics;
|
||||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
|
import org.apache.tomcat.util.modeler.Registry;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
|
|
@ -33,11 +35,13 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex
|
||||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
|
||||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
||||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.server.reactive.HttpHandler;
|
import org.springframework.http.server.reactive.HttpHandler;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
@ -51,6 +55,7 @@ public class TomcatMetricsAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoConfiguresTomcatMetricsWithEmbeddedServletTomcat() {
|
public void autoConfiguresTomcatMetricsWithEmbeddedServletTomcat() {
|
||||||
|
resetTomcatState();
|
||||||
new WebApplicationContextRunner(
|
new WebApplicationContextRunner(
|
||||||
AnnotationConfigServletWebServerApplicationContext::new)
|
AnnotationConfigServletWebServerApplicationContext::new)
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
|
|
@ -58,6 +63,7 @@ public class TomcatMetricsAutoConfigurationTests {
|
||||||
ServletWebServerFactoryAutoConfiguration.class))
|
ServletWebServerFactoryAutoConfiguration.class))
|
||||||
.withUserConfiguration(ServletWebServerConfiguration.class,
|
.withUserConfiguration(ServletWebServerConfiguration.class,
|
||||||
MeterRegistryConfiguration.class)
|
MeterRegistryConfiguration.class)
|
||||||
|
.withPropertyValues("server.tomcat.mbeanregistry.enabled=true")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.publishEvent(
|
context.publishEvent(
|
||||||
new ApplicationStartedEvent(new SpringApplication(),
|
new ApplicationStartedEvent(new SpringApplication(),
|
||||||
|
|
@ -75,6 +81,7 @@ public class TomcatMetricsAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoConfiguresTomcatMetricsWithEmbeddedReactiveTomcat() {
|
public void autoConfiguresTomcatMetricsWithEmbeddedReactiveTomcat() {
|
||||||
|
resetTomcatState();
|
||||||
new ReactiveWebApplicationContextRunner(
|
new ReactiveWebApplicationContextRunner(
|
||||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
|
|
@ -82,6 +89,7 @@ public class TomcatMetricsAutoConfigurationTests {
|
||||||
ReactiveWebServerFactoryAutoConfiguration.class))
|
ReactiveWebServerFactoryAutoConfiguration.class))
|
||||||
.withUserConfiguration(ReactiveWebServerConfiguration.class,
|
.withUserConfiguration(ReactiveWebServerConfiguration.class,
|
||||||
MeterRegistryConfiguration.class)
|
MeterRegistryConfiguration.class)
|
||||||
|
.withPropertyValues("server.tomcat.mbeanregistry.enabled=true")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.publishEvent(
|
context.publishEvent(
|
||||||
new ApplicationStartedEvent(new SpringApplication(),
|
new ApplicationStartedEvent(new SpringApplication(),
|
||||||
|
|
@ -130,6 +138,13 @@ public class TomcatMetricsAutoConfigurationTests {
|
||||||
.hasBean("customTomcatMetrics"));
|
.hasBean("customTomcatMetrics"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetTomcatState() {
|
||||||
|
ReflectionTestUtils.setField(Registry.class, "registry", null);
|
||||||
|
AtomicInteger containerCounter = (AtomicInteger) ReflectionTestUtils
|
||||||
|
.getField(TomcatWebServer.class, "containerCounter");
|
||||||
|
containerCounter.set(-1);
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class MeterRegistryConfiguration {
|
static class MeterRegistryConfiguration {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.validation.Configuration;
|
import javax.validation.Configuration;
|
||||||
import javax.validation.Validation;
|
import javax.validation.Validation;
|
||||||
|
|
||||||
import org.apache.catalina.mbeans.MBeanFactory;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
||||||
|
|
@ -99,7 +97,6 @@ public class BackgroundPreinitializer
|
||||||
runSafely(new ConversionServiceInitializer());
|
runSafely(new ConversionServiceInitializer());
|
||||||
runSafely(new ValidationInitializer());
|
runSafely(new ValidationInitializer());
|
||||||
runSafely(new MessageConverterInitializer());
|
runSafely(new MessageConverterInitializer());
|
||||||
runSafely(new MBeanFactoryInitializer());
|
|
||||||
runSafely(new JacksonInitializer());
|
runSafely(new JacksonInitializer());
|
||||||
runSafely(new CharsetInitializer());
|
runSafely(new CharsetInitializer());
|
||||||
preinitializationComplete.countDown();
|
preinitializationComplete.countDown();
|
||||||
|
|
@ -137,18 +134,6 @@ public class BackgroundPreinitializer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Early initializer to load Tomcat MBean XML.
|
|
||||||
*/
|
|
||||||
private static class MBeanFactoryInitializer implements Runnable {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
new MBeanFactory();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Early initializer for javax.validation.
|
* Early initializer for javax.validation.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -400,6 +400,11 @@ public class ServerProperties {
|
||||||
*/
|
*/
|
||||||
private final Resource resource = new Resource();
|
private final Resource resource = new Resource();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modeler MBean Registry configuration.
|
||||||
|
*/
|
||||||
|
private final Mbeanregistry mbeanregistry = new Mbeanregistry();
|
||||||
|
|
||||||
public int getMaxThreads() {
|
public int getMaxThreads() {
|
||||||
return this.maxThreads;
|
return this.maxThreads;
|
||||||
}
|
}
|
||||||
|
|
@ -552,6 +557,10 @@ public class ServerProperties {
|
||||||
return this.resource;
|
return this.resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Mbeanregistry getMbeanregistry() {
|
||||||
|
return this.mbeanregistry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tomcat access log properties.
|
* Tomcat access log properties.
|
||||||
*/
|
*/
|
||||||
|
|
@ -821,6 +830,23 @@ public class ServerProperties {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Mbeanregistry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Tomcat's MBean Registry should be enabled.
|
||||||
|
*/
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return this.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import reactor.netty.http.server.HttpServer;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||||
|
|
@ -98,6 +99,12 @@ abstract class ReactiveWebServerFactoryConfiguration {
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TomcatReactiveWebServerFactoryCustomizer tomcatReactiveWebServerFactoryCustomizer(
|
||||||
|
ServerProperties serverProperties) {
|
||||||
|
return new TomcatReactiveWebServerFactoryCustomizer(serverProperties);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.web.reactive;
|
||||||
|
|
||||||
|
import org.apache.tomcat.util.modeler.Registry;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||||
|
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Tomcat reactive
|
||||||
|
* web servers.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 2.2.0
|
||||||
|
*/
|
||||||
|
public class TomcatReactiveWebServerFactoryCustomizer
|
||||||
|
implements WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> {
|
||||||
|
|
||||||
|
private final ServerProperties serverProperties;
|
||||||
|
|
||||||
|
public TomcatReactiveWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||||
|
this.serverProperties = serverProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(TomcatReactiveWebServerFactory factory) {
|
||||||
|
if (!this.serverProperties.getTomcat().getMbeanregistry().isEnabled()) {
|
||||||
|
Registry.disableRegistry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.web.servlet;
|
package org.springframework.boot.autoconfigure.web.servlet;
|
||||||
|
|
||||||
|
import org.apache.tomcat.util.modeler.Registry;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
|
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||||
|
|
@ -60,6 +62,9 @@ public class TomcatServletWebServerFactoryCustomizer
|
||||||
customizeUseRelativeRedirects(factory,
|
customizeUseRelativeRedirects(factory,
|
||||||
tomcatProperties.getUseRelativeRedirects());
|
tomcatProperties.getUseRelativeRedirects());
|
||||||
}
|
}
|
||||||
|
if (!tomcatProperties.getMbeanregistry().isEnabled()) {
|
||||||
|
Registry.disableRegistry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void customizeRedirectContextRoot(ConfigurableTomcatWebServerFactory factory,
|
private void customizeRedirectContextRoot(ConfigurableTomcatWebServerFactory factory,
|
||||||
|
|
|
||||||
|
|
@ -1075,6 +1075,20 @@ include::{code-examples}/context/embedded/TomcatLegacyCookieProcessorExample.jav
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[howto-enable-tomcat-mbean-registry]]
|
||||||
|
=== Enable Tomcat's MBean Registry
|
||||||
|
Embedded Tomcat's MBean registry is disabled by default. This minimizes Tomcat's memory
|
||||||
|
footprint. If you want to use Tomcat's MBeans, for example so that they can be used to
|
||||||
|
expose metrics via Micrometer, you must use the `server.tomcat.mbeanregistry.enabled`
|
||||||
|
property to do so, as shown in the following example:
|
||||||
|
|
||||||
|
[source,properties,indent=0]
|
||||||
|
----
|
||||||
|
server.tomcat.mbeanregistry.enabled=true
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-enable-multiple-listeners-in-undertow]]
|
[[howto-enable-multiple-listeners-in-undertow]]
|
||||||
=== Enable Multiple Listeners with Undertow
|
=== Enable Multiple Listeners with Undertow
|
||||||
Add an `UndertowBuilderCustomizer` to the `UndertowServletWebServerFactory` and
|
Add an `UndertowBuilderCustomizer` to the `UndertowServletWebServerFactory` and
|
||||||
|
|
|
||||||
|
|
@ -1793,7 +1793,8 @@ Spring Boot registers the following core metrics when applicable:
|
||||||
* Logback metrics: record the number of events logged to Logback at each level
|
* Logback metrics: record the number of events logged to Logback at each level
|
||||||
* Uptime metrics: report a gauge for uptime and a fixed gauge representing the
|
* Uptime metrics: report a gauge for uptime and a fixed gauge representing the
|
||||||
application's absolute start time
|
application's absolute start time
|
||||||
* Tomcat metrics
|
* Tomcat metrics (`server.tomcat.mbeanregistry.enabled` must be set to `true` for all
|
||||||
|
Tomcat metrics to be registered)
|
||||||
* https://docs.spring.io/spring-integration/docs/current/reference/html/system-management-chapter.html#micrometer-integration[Spring Integration] metrics
|
* https://docs.spring.io/spring-integration/docs/current/reference/html/system-management-chapter.html#micrometer-integration[Spring Integration] metrics
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue