SpringBoot应用当中,默认情况下Actuator与应用程序在相同的端口号启动。但是可能会存在一些场景(比如主程序可能是需要对外暴露的,但是Actuator只是内网暴露的),需要将Actuator与应用程序的主端口隔离开。
可以参考如下的配置,其中server.port
配置的是主程序的端口号,management.server.port
则配置的是Actuator的端口号。
server.port=8080
management.server.port=8891
配置后,Actuator就无法在8080端口访问,需要在8891端口进行访问。
Actuator与应用程序端口隔离的代码位置如下:
// org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration
@AutoConfiguration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
@EnableConfigurationProperties({ WebEndpointProperties.class, ManagementServerProperties.class })
public class ManagementContextAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnManagementPort(ManagementPortType.SAME)
static class SameManagementContextConfiguration implements SmartInitializingSingleton {
private final Environment environment;
SameManagementContextConfiguration(Environment environment) {
this.environment = environment;
}
@Override
public void afterSingletonsInstantiated() {
verifySslConfiguration();
verifyAddressConfiguration();
if (this.environment instanceof ConfigurableEnvironment configurableEnvironment) {
addLocalManagementPortPropertyAlias(configurableEnvironment);
}
}
private void verifySslConfiguration() {
Boolean enabled = this.environment.getProperty("management.server.ssl.enabled", Boolean.class, false);
Assert.state(!enabled, "Management-specific SSL cannot be configured as the management "
+ "server is not listening on a separate port");
}
private void verifyAddressConfiguration() {
Object address = this.environment.getProperty("management.server.address");
Assert.state(address == null, "Management-specific server address cannot be configured as the management "
+ "server is not listening on a separate port");
}
/**
* Add an alias for 'local.management.port' that actually resolves using
* 'local.server.port'.
* @param environment the environment
*/
private void addLocalManagementPortPropertyAlias(ConfigurableEnvironment environment) {
environment.getPropertySources().addLast(new PropertySource<>("Management Server") {
@Override
public Object getProperty(String name) {
if ("local.management.port".equals(name)) {
return environment.getProperty("local.server.port");
}
return null;
}
});
}
@Configuration(proxyBeanMethods = false)
@EnableManagementContext(ManagementContextType.SAME)
static class EnableSameManagementContextConfiguration {
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
static class DifferentManagementContextConfiguration {
@Bean
static ChildManagementContextInitializer childManagementContextInitializer(
ManagementContextFactory managementContextFactory, ApplicationContext parentContext) {
return new ChildManagementContextInitializer(managementContextFactory, parentContext);
}
}
}
其中会去识别management.server.port
和server.port
不一致(ManagementPortType=DIFFERENT
)的话,那么将会使用ChildManagementContextInitializer
去创建一个子ApplicationContext,专门用来处理Actuator相关的接口。