Web应用服务中如果利用Actuator提供服务的相关健康指标就需要利用ManagementContextAutoConfiguration
重启一个子容器。该子容器监听的端口区别于服务端口,由此则引申出不同类型的ManagementContextType。
Actuator
:中文含义为执行器。在 Spring Boot 中 Actuator 负责对 Endpoint 进行自动装配、协议解析、服务调度,是 Endpoint 的功能集合。它集成了很多监控功能于一体,由于做了大量的底层工作,使得对 Endpoint 的访问和扩展非常方便。
Endpoint
:中文含义为端点。在 Spring Boot 中 Endpoint 负责对外暴露服务,负责实现一个具体的业务监控指标,提供具体实现,类似于接口,其端点映射到一个 URL,可以采用 HTTP 或者 JMX 协议进行访问,从而实现监控与应用的交互。
枚举类ManagementContextType
包含枚举类型:SAME、CHILD、ANY三种。
ConditionalOnAvailableEndpoint
ConditionalOnWebApplication
1、创建子容器
@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
@EnableConfigurationProperties({ WebEndpointProperties.class, ManagementServerProperties.class })
public class ManagementContextAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnManagementPort(ManagementPortType.SAME)
static class SameManagementContextConfiguration implements SmartInitializingSingleton {}
@Configuration(proxyBeanMethods = false)
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
static class DifferentManagementContextConfiguration implements ApplicationListener<WebServerInitializedEvent> {
private final ApplicationContext applicationContext;
//Management对应的子容器工厂类:ServletManagementContextFactory、ReactiveManagementContextFactory
private final ManagementContextFactory managementContextFactory;
public DifferentManagementContextConfiguration(ApplicationContext app,ManagementContextFactory mcf) {
this.applicationContext = app;// 父容器
// 子容器工厂类:ServletManagementContextFactory
this.managementContextFactory = mcf;
}
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
if (event.getApplicationContext().equals(this.applicationContext)) {
ConfigurableWebServerApplicationContext managementContext = this.managementContextFactory
.createManagementContext(this.applicationContext,
EnableChildManagementContextConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
...
// 重新刷新IOC容器,其中包括新启动一个Tomcat容器。启动过程中涉及的配置信息由ManagementServerProperties提供
managementContext.refresh();
}
}
}
}
DifferentManagementContextConfiguration作为父容器的一个监听器ApplicationListener,在触发事件WebServerInitializedEvent时负责启动management的子容器。
子容器创建过程也即SpringBoot初始化IOC容器过程:
- 首先,子容器应用上下文默认类型为AnnotationConfigServletWebServerApplicationContext。
- 其次,子容器内部提前注册三个类ServletWebServerFactoryAutoConfiguration、EnableChildManagementContextConfiguration、PropertyPlaceholderAutoConfiguration。这三个类充当的角色相当于@SpringBootApplication注解的启动类。
其中,Servlet容器工厂类ServletWebServerFactoryAutoConfiguration作用是根据配置动态选择Tomcat、Jetty等Servlet容器;类EnableChildManagementContextConfiguration则负责通过@Import注解导入选择器DeferredImportSelector之ManagementContextConfigurationImportSelector
。
以下章节的执行均是由当前创建的IOC容器managementContext触发执行的。运行过程是Management对应的Web应用服务。
- 注解
@ConditionalOnManagementPort
通过management.server.port与server.port是否相同选择SameManagementContextConfiguration【smcc】 or DifferentManagementContextConfiguration【dmcc】。 - smcc & dmcc 都是利用
注解@EnableManagementContext
引入核心类ManagementContextConfigurationImportSelector
。
2.ImportSelector
注解@EnableManagementContext的角色类似于@SpringBootApplication
。区别是前者通过@Import引入ImportSelector的子类为ManagementContextConfigurationImportSelector。ImportSelector相关子类其作用就是从类路径下加载容器所关注的自动装配类。例如,@SpringBootApplication导入的ImportSelector相关子类关注的是spring.factories文件中候选类,而后者关注的是ManagementContextConfiguration注解的候选类。
- 利用@EnableManagementContext其value属性得到ManagementContextType。
- 利用SPI机制加载
META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.imports
路劲下注解@ManagementContextConfiguration
标识的目标类。当前上述路径也即ManagementContextConfiguration的包路径。 - 利用ManagementContextType过滤步骤2中的目标类。注解@EnableManagementContext 与 注解@ManagementContextConfiguration显式指定的ManagementContextConfiguration类型必须一致,如果不一致则后者ManagementContextConfiguration类型必须为Any。
class ManagementContextConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
// contextType 为 CHILD
String clazzName = EnableManagementContext.class.getName();
Object o = metadata.getAnnotationAttributes(clazzName).get("value")
ManagementContextType contextType = (ManagementContextType) o;
// Find all management context configuration classes, filtering duplicates
List<ManagementConfiguration> configurations = getConfigurations();
OrderComparator.sort(configurations);
List<String> names = new ArrayList<>();
for (ManagementConfiguration configuration : configurations) {
ManagementContextType ct = configuration.getContextType();
// 保留 ct 为ANY 或者 CHILD的ManagementConfiguration
if (ct == ManagementContextType.ANY || ct == contextType) {
names.add(configuration.getClassName());
}
}
return StringUtils.toStringArray(names);
}
private List<ManagementConfiguration> getConfigurations() {
SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory(this.classLoader);
List<ManagementConfiguration> configurations = new ArrayList<>();
for (String className : loadFactoryNames()) {
addConfiguration(readerFactory, configurations, className);
}
return configurations;
}
private void addConfiguration(SimpleMetadataReaderFactory readerFactory,
List<ManagementConfiguration> configurations, String className) {
MetadataReader metadataReader = readerFactory.getMetadataReader(className);
configurations.add(new ManagementConfiguration(metadataReader));
}
// ManagementContextConfiguration:注解
protected List<String> loadFactoryNames() {
List<String> factoryNames = SpringFactoriesLoader.loadFactoryNames(ManagementContextConfiguration.class,
this.classLoader);
// 首先从SpringBoot中自动装配类中查找ManagementContextConfiguration类型的类
List<String> factoryNames = new ArrayList<>(factoryNames);
// 否则从 META-INF/spring/%s.imports,其中%s为注解ManagementContextConfiguration的类名,即
// META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.imports,如截图所示
ImportCandidates.load(ManagementContextConfiguration.class, this.classLoader).forEach(factoryNames::add);
return factoryNames;
}
...
}
借助Spi机制从spring.factories文件获取被注解@ManagementContextConfiguration
标识的候选类:
默认10种类型注解@ManagementContextConfiguration标识的目标类中,着重分析如下的核心类。
org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration
org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration
...
org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration
org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration
该注解value属性类型为ManagementContextType,支持使用时显式指定类型ManagementContextType,默认为Any。
2.1.ServletEndpointManagementContextConfiguration
@ManagementContextConfiguration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
public class ServletEndpointManagementContextConfiguration {
@Bean
public IncludeExcludeEndpointFilter<ExposableServletEndpoint>
servletExposeExcludePropertyEndpointFilter(WebEndpointProperties properties) {
WebEndpointProperties.Exposure exposure = properties.getExposure();
Set<String> include = exposure.getInclude();
Set<String> exclude = exposure.getExclude();
return new IncludeExcludeEndpointFilter<>(ExposableServletEndpoint.class,include,exclude);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(DispatcherServlet.class)
public static class WebMvcServletEndpointManagementContextConfiguration {
@Bean
public ServletEndpointRegistrar servletEndpointRegistrar(WebEndpointProperties properties,
ServletEndpointsSupplier servletEndpointsSupplier,
DispatcherServletPath dispatcherServletPath) {
String path = dispatcherServletPath.getRelativePath(properties.getBasePath());
return new ServletEndpointRegistrar(path,servletEndpointsSupplier.getEndpoints());
}
}
}
2.2.WebMvcEndpointManagementContextConfiguration
当前核心类负责SpringMVC九大组件之HandlerMapping。在Actuator中新增两种类型的HandlerMapping之WebMvcEndpointHandlerMapping
、ControllerEndpointHandlerMapping
,使得Actuator可以访问相关接口actuator/health
、actuator/prometheus
。
@ManagementContextConfiguration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@ConditionalOnBean({ DispatcherServlet.class, WebEndpointsSupplier.class })
@EnableConfigurationProperties(CorsEndpointProperties.class)
public class WebMvcEndpointManagementContextConfiguration {
@Bean
@ConditionalOnMissingBean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(
WebEndpointsSupplier webEndpointsSupplier,
ServletEndpointsSupplier servletEndpointsSupplier,
ControllerEndpointsSupplier controllerEndpointsSupplier,
EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties, Environment environment) {
// 获取全部类型的ExposableEndpoint
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
//尝试触发 WebEndpointDiscoverer 加载全部当前类型的 ExposableEndpoint
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
allEndpoints.addAll(webEndpoints);
//尝试触发 ServletEndpointDiscoverer 加载全部当前类型的 ExposableEndpoint
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
//尝试触发 ControllerEndpointDiscoverer 加载全部当前类型的 ExposableEndpoint
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
//basePath:/actuator
String basePath = webEndpointProperties.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath),
shouldRegisterLinksMapping, WebMvcAutoConfiguration.pathPatternParser);
}
...
}
public class WebMvcEndpointManagementContextConfiguration {
@Bean
@ConditionalOnMissingBean
public ControllerEndpointHandlerMapping controllerEndpointHandlerMapping(
ControllerEndpointsSupplier controllerEndpointsSupplier, CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties) {
EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
return new ControllerEndpointHandlerMapping(endpointMapping, controllerEndpointsSupplier.getEndpoints(),
corsProperties.toCorsConfiguration());
}
}
2.2.1.SpringMVC中注册HandlerMapping
WebMvcEndpointHandlerMapping、AbstractWebMvcEndpointHandlerMapping是Actuator单独提供的HandlerMapping。
如果所示WebMvcEndpointHandlerMapping存在接口InitializingBean:
public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappingInfoHandlerMapping
implements InitializingBean, MatchableHandlerMapping {
public void afterPropertiesSet() {
...
//AbstractHandlerMethodMapping#afterPropertiesSet
super.afterPropertiesSet();
initHandlerMethods();
}
@Override
protected void initHandlerMethods() {
for (ExposableWebEndpoint endpoint : this.endpoints) {//遍历全部的可暴露的Endpoint
for (WebOperation operation : endpoint.getOperations()) {
registerMappingForOperation(endpoint, operation);
}
}
...
}
private void registerMappingForOperation(ExposableWebEndpoint endpoint, WebOperation operation) {
WebOperationRequestPredicate predicate = operation.getRequestPredicate();
String path = predicate.getPath();// 就是目标Endpoint类上@Endpoint注解指定的值
String matchAllRemainingPathSegmentsVariable = predicate.getMatchAllRemainingPathSegmentsVariable();
if (matchAllRemainingPathSegmentsVariable != null) {
path = path.replace("{*" + matchAllRemainingPathSegmentsVariable + "}", "**");
}
registerMapping(endpoint, predicate, operation, path);
}
protected void registerMapping(ExposableWebEndpoint endpoint, WebOperationRequestPredicate predicate,
WebOperation operation, String path) {
...
RequestMappingInfo info = createRequestMappingInfo(predicate, path);
// 最终注册到SpringMVC,提供健康检查、普罗米修斯指标监控指标获取接口
registerMapping(info, new OperationHandler(servletWebOperation),this.handleMethod);
}
private RequestMappingInfo createRequestMappingInfo(WebOperationRequestPredicate predicate, String path) {
//拼接最终访问地址:actuator/health、actuator/prometheus
return RequestMappingInfo.paths(this.endpointMapping.createSubPath(path))
.options(this.builderConfig)
.methods(RequestMethod.valueOf(predicate.getHttpMethod().name()))
.consumes(predicate.getConsumes().toArray(new String[0]))
.produces(predicate.getProduces().toArray(new String[0]))
.build();
}
}
2.3.ServletManagementChildContextConfiguration
该配置类是为了初始化类ServletManagementWebServerFactoryCustomizer。ServletManagementWebServerFactoryCustomizer的作用参考公共后置处理器。
@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
class ServletManagementChildContextConfiguration {
static class ServletManagementWebServerFactoryCustomizer
extends ManagementWebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
ServletManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory) {
super(beanFactory, ServletWebServerFactoryCustomizer.class, TomcatServletWebServerFactoryCustomizer.class,
TomcatWebServerFactoryCustomizer.class, JettyWebServerFactoryCustomizer.class,
UndertowServletWebServerFactoryCustomizer.class, UndertowWebServerFactoryCustomizer.class);
}
@Override
protected void customize(ConfigurableServletWebServerFactory webServerFactory,// 步骤2
ManagementServerProperties managementServerProperties, ServerProperties serverProperties) {
// webServerFactory:TomcatServletWebServerFactory 或者 JettyServletWebServerFactory
// 调用抽象类ManagementWebServerFactoryCustomizer
super.customize(webServerFactory, managementServerProperties, serverProperties);
webServerFactory.setContextPath(getContextPath(managementServerProperties));
}
//设置Management对应Web服务的ContextPath
private String getContextPath(ManagementServerProperties managementServerProperties) {
String basePath = managementServerProperties.getBasePath();
return StringUtils.hasText(basePath) ? basePath : "";
}
}
}
public abstract class ManagementWebServerFactoryCustomizer<T extends ConfigurableWebServerFactory>
implements WebServerFactoryCustomizer<T>, Ordered {
@Override
public final void customize(T factory) {// 步骤1
ManagementServerProperties managementServerProperties = BeanFactoryUtils
.beanOfTypeIncludingAncestors(this.beanFactory, ManagementServerProperties.class);
customizeSameAsParentContext(factory);
ServerProperties serverProperties = BeanFactoryUtils.beanOfTypeIncludingAncestors(this.beanFactory,
ServerProperties.class);
// 调用该抽象类的子类之ServletManagementWebServerFactoryCustomizer
customize(factory, managementServerProperties, serverProperties);
}
protected void customize(T factory, ManagementServerProperties managementServerProperties,
ServerProperties serverProperties) {
factory.setPort(managementServerProperties.getPort());//设置Management对应Web服务的端口号
...
factory.setServerHeader(serverProperties.getServerHeader());
factory.setAddress(managementServerProperties.getAddress());
}
}
2.4.WebMvcEndpointChildContextConfiguration
该核心类主要提供子容器的SpringMVC相关九大组件的核心类,包括:DispatcherServlet
、DispatcherServletRegistrationBean
、HandlerMapping之CompositeHandlerMapping
、CompositeHandlerAdapter
、CompositeHandlerExceptionResolver
、RequestContextFilter
等。
3、可暴露端点ExposableEndpoint
如图所示,整体上 可暴露端点ExposableEndpoint
分为三类DiscoveredServletEndpoint、DiscoveredWebEndpoint、DiscoveredControllerEndpoint。
如图所示,针对上述三大类型的ExposableEndpoint,存在三大类型的Discoverer对其完成加载。
其中,自动装配类WebEndpointAutoConfiguration
引入三大类型Discoverer相关的候选类。
3.1.获取全部的Endpoint
A Base for {@link EndpointsSupplier} implementations that discover {@link Endpoint @Endpoint} beans and {@link EndpointExtension @EndpointExtension} beans in an application context。
其子类实例化过程中触发抽象类解析得到@Endpoint、@WebEndpoint
标识的全部目标类。
public abstract class EndpointDiscoverer implements EndpointsSupplier<E> {
private volatile Collection<E> endpoints;
@Override
public final Collection<E> getEndpoints() {
if (this.endpoints == null) {
this.endpoints = discoverEndpoints();
}
return this.endpoints;
}
private Collection<E> discoverEndpoints() {
Collection<EndpointBean> endpointBeans = createEndpointBeans();
addExtensionBeans(endpointBeans);
return convertToEndpoints(endpointBeans);
}
private Collection<EndpointBean> createEndpointBeans() {
Map<EndpointId, EndpointBean> byId = new LinkedHashMap<>();
String[] beanNames =
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext,Endpoint.class);
for (String beanName : beanNames) {
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
EndpointBean endpointBean = createEndpointBean(beanName);
EndpointBean previous = byId.putIfAbsent(endpointBean.getId(), endpointBean);
}
}
return byId.values();
}
}
3.1.1.WebEndpointDiscoverer
内部创建DiscoveredWebEndpoint。
3.1.2.ControllerEndpointDiscoverer
内部创建DiscoveredControllerEndpoint。
3.1.3.ServletEndpointDiscoverer
内部创建DiscoveredServletEndpoint。
4、条件开关控制ExposableEndpoint
class OnAvailableEndpointCondition extends SpringBootCondition {
...
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
MergedAnnotations ma = metadata.getAnnotations();
// 获取注解ConditionalOnAvailableEndpoint存在的相关属性
MergedAnnotation conditionAnnotation = ma.get(ConditionalOnAvailableEndpoint.class);
// 获取注解ConditionalOnAvailableEndpoint中类型为Class的endpoint属性,例如PrometheusScrapeEndpoint
Class<?> target = getTarget(context, metadata, conditionAnnotation);
// 解析类target存在的注解@Endpoint
MergedAnnotation<Endpoint> endpointAnnotation = getEndpointAnnotation(target);
return getMatchOutcome(environment, conditionAnnotation, endpointAnnotation);
}
private ConditionOutcome getMatchOutcome(Environment environment,
MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation,
MergedAnnotation<Endpoint> endpointAnnotation) {
ConditionMessage.Builder message = ConditionMessage.forCondition(ConditionalOnAvailableEndpoint.class);
// 获取 注解@Endpoint 之ID属性,例如prometheus
EndpointId endpointId = EndpointId.of(environment, endpointAnnotation.getString("id"));
...
Set<EndpointExposure> exposuresToCheck = getExposuresToCheck(conditionAnnotation);
Set<ExposureFilter> exposureFilters = getExposureFilters(environment);
for (ExposureFilter exposureFilter : exposureFilters) {
//判断环境变量中配置的Endpoint是否存在当前EndpointId
if (exposuresToCheck.contains(exposureFilter.getExposure()) && exposureFilter.isExposed(endpointId)) {
return ConditionOutcome.match(...);
}
}
return ConditionOutcome.noMatch(message.because("no 'management.endpoints' property marked it as exposed"));
}
static final class ExposureFilter extends IncludeExcludeEndpointFilter<ExposableEndpoint<?>> {
@SuppressWarnings({ "unchecked", "rawtypes" })
private ExposureFilter(Environment environment, EndpointExposure exposure) {
//management.endpoints.web.exposure.include
//management.endpoints.web.exposure.exclude
String prefix = "management.endpoints." + getCanonicalName(exposure) + ".exposure";
super((Class) ExposableEndpoint.class, environment,prefix, exposure.getDefaultIncludes());
this.exposure = exposure;
}
boolean isExposed(EndpointId id) {//此处ID是指@Endpoint注解指定的ID
// 利用Environment读取上述prefix对应的配置值
return super.match(id);
}
}
}
ExposureFilter构造器参数EndpointExposure存在三种类型:JMX、CLOUD_FOUNDRY、WEB。
分别对应各自条件前缀:
- management.endpoints.web.exposure.include。
- management.endpoints.jmx.exposure.include。
- management.endpoints.cloud_foundry.exposure.include。
利用Environment读取上述前缀的value属性,最终判断value集合中是否存在EndpointId类型的ID。
5、示例之普罗米修斯之Prometheus
@AutoConfiguration(before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class },after = MetricsAutoConfiguration.class)
@ConditionalOnBean(Clock.class)
@ConditionalOnClass(PrometheusMeterRegistry.class)
//利用 management.metrics.export.prometheus.enabled 开关配置来控制 Prometheus 相关功能是否生效。默认值为true
@ConditionalOnEnabledMetricsExport("prometheus")
@EnableConfigurationProperties(PrometheusProperties.class)
public class PrometheusMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public PrometheusConfig prometheusConfig(PrometheusProperties prometheusProperties) {
return new PrometheusPropertiesConfigAdapter(prometheusProperties);
}
@Bean
@ConditionalOnMissingBean
public PrometheusMeterRegistry prometheusMeterRegistry(PrometheusConfig prometheusConfig,
CollectorRegistry collectorRegistry, Clock clock,
ObjectProvider<ExemplarSampler> exemplarSamplerProvider) {
ExemplarSampler exemplarSampler = exemplarSamplerProvider.getIfAvailable();
return new PrometheusMeterRegistry(prometheusConfig, collectorRegistry, clock,exemplarSampler);
}
@Bean
@ConditionalOnMissingBean
public CollectorRegistry collectorRegistry() {
return new CollectorRegistry(true);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnAvailableEndpoint(endpoint = PrometheusScrapeEndpoint.class)
public static class PrometheusScrapeEndpointConfiguration {
@Bean
@ConditionalOnMissingBean
public PrometheusScrapeEndpoint prometheusEndpoint(CollectorRegistry collectorRegistry) {
return new PrometheusScrapeEndpoint(collectorRegistry);
}
}
}
创建核心类PrometheusScrapeEndpoint。
6.常规配置
自动配置类ManagementContextAutoConfiguration引入两个配置类:WebEndpointProperties & ManagementServerProperties。
- ManagementServerProperties配置前缀为management.server。
management.server.port
management.server.address
//默认为空字符串
management.server.basePath
- WebEndpointProperties配置前缀为management.endpoints.web。
//默认值为/actuator
management.endpoints.web.basePath
management.endpoints.web.exposure.include
management.endpoints.web.exposure.exclude
management.endpoints.web.pathMapping
management.endpoints.web.discovery.enabled
综上所述健康检查路径为:
http://management.server.address:management.server.port/management.server.basePath/management.endpoints.web.basePath/health
http://localhost:59111/blink/actuator/health
6.1.常见配置如下:
management.server.port = 50000
management.servlet.contextPath = /
management.metrics.tags.application = ${spring.application.name}
management.metrics.export.prometheus.enabled = true
management.metrics.export.prometheus.step = 1m
management.metrics.export.prometheus.descriptions = true
management.endpoint.health.show-details = always
//默认健康检查路径为http://localhost:59111/actuator/health,如下配置直接修改默认路径从而导致健康检查无法调用
management.endpoints.web.base-path = /
management.endpoint.prometheus.enabled = true
management.endpoint.shutdown.enabled = true
management.endpoint.health.probes.enabled = true
management.endpoints.prometheus.id = springmetrics
management.endpoints.web.exposure.include = health,shutdown,metrics,prometheus
7.延伸点
在健康检查spring-boot-starter-actuator包下存在一个与Management相关的自动配置类ManagementContextAutoConfiguration,所在包、以及文件如下所示: