Actuator之Management

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容器过程:

  1. 首先,子容器应用上下文默认类型为AnnotationConfigServletWebServerApplicationContext。
  2. 其次,子容器内部提前注册三个类ServletWebServerFactoryAutoConfiguration、EnableChildManagementContextConfiguration、PropertyPlaceholderAutoConfiguration。这三个类充当的角色相当于@SpringBootApplication注解的启动类。
    其中,Servlet容器工厂类ServletWebServerFactoryAutoConfiguration作用是根据配置动态选择Tomcat、Jetty等Servlet容器;类EnableChildManagementContextConfiguration则负责通过@Import注解导入选择器DeferredImportSelector之ManagementContextConfigurationImportSelector

以下章节的执行均是由当前创建的IOC容器managementContext触发执行的。运行过程是Management对应的Web应用服务。

  1. 注解@ConditionalOnManagementPort通过management.server.port与server.port是否相同选择SameManagementContextConfiguration【smcc】 or DifferentManagementContextConfiguration【dmcc】。
  2. smcc & dmcc 都是利用 注解@EnableManagementContext 引入核心类ManagementContextConfigurationImportSelector

2.ImportSelector

注解@EnableManagementContext的角色类似于@SpringBootApplication。区别是前者通过@Import引入ImportSelector的子类为ManagementContextConfigurationImportSelector。ImportSelector相关子类其作用就是从类路径下加载容器所关注的自动装配类。例如,@SpringBootApplication导入的ImportSelector相关子类关注的是spring.factories文件中候选类,而后者关注的是ManagementContextConfiguration注解的候选类。

  1. 利用@EnableManagementContext其value属性得到ManagementContextType。
  2. 利用SPI机制加载META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.imports路劲下注解@ManagementContextConfiguration标识的目标类。当前上述路径也即ManagementContextConfiguration的包路径。
  3. 利用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之WebMvcEndpointHandlerMappingControllerEndpointHandlerMapping,使得Actuator可以访问相关接口actuator/healthactuator/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相关九大组件的核心类,包括:DispatcherServletDispatcherServletRegistrationBean、HandlerMapping之CompositeHandlerMappingCompositeHandlerAdapterCompositeHandlerExceptionResolverRequestContextFilter等。

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,所在包、以及文件如下所示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值