时间:2021-05-19
SpringBoot自动装配的套路,直接看 spring.factories 文件,当我们使用的时候只需要引入如下依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>然后在 org.springframework.boot.spring-boot-actuator-autoconfigure 包下去就可以找到这个文件
查看这个文件发现引入了很多的配置类,这里先关注一下 XXXHealthIndicatorAutoConfiguration 系列的类,这里咱们拿第一个 RabbitHealthIndicatorAutoConfiguration 为例来解析一下。看名字就知道这个是RabbitMQ的健康检查的自动配置类
@Configuration@ConditionalOnClass(RabbitTemplate.class)@ConditionalOnBean(RabbitTemplate.class)@ConditionalOnEnabledHealthIndicator("rabbit")@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)@AutoConfigureAfter(RabbitAutoConfiguration.class)public class RabbitHealthIndicatorAutoConfiguration extends CompositeHealthIndicatorConfiguration<RabbitHealthIndicator, RabbitTemplate> { private final Map<String, RabbitTemplate> rabbitTemplates; public RabbitHealthIndicatorAutoConfiguration( Map<String, RabbitTemplate> rabbitTemplates) { this.rabbitTemplates = rabbitTemplates; } @Bean @ConditionalOnMissingBean(name = "rabbitHealthIndicator") public HealthIndicator rabbitHealthIndicator() { return createHealthIndicator(this.rabbitTemplates); }}按照以往的惯例,先解析注解
上方的入口方法是 SpringBootCondition 类的 matches 方法, getMatchOutcome 这个方法则是子类 OnEndpointElementCondition 的,这个方法首先会去环境变量中查找是否存在 management.health.rabbit.enabled 属性,如果没有的话则去查找 management.health.defaults.enabled 属性,如果这个属性还没有的话则设置默认值为true
当这里返回true时整个 RabbitHealthIndicatorAutoConfiguration 类的自动配置才能继续下去
首先这个类引入了配置文件 HealthIndicatorProperties 这个配置类是系统状态相关的配置
@ConfigurationProperties(prefix = "management.health.status")public class HealthIndicatorProperties { private List<String> order = null; private final Map<String, Integer> httpMapping = new HashMap<>();}接着就是注册了2个bean ApplicationHealthIndicator 和 OrderedHealthAggregator 这两个bean的作用稍后再说,现在回到 RabbitHealthIndicatorAutoConfiguration 类
@AutoConfigureAfterHealthIndicatorpublic abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndicator, S> { @Autowired private HealthAggregator healthAggregator; protected HealthIndicator createHealthIndicator(Map<String, S> beans) { if (beans.size() == 1) { return createHealthIndicator(beans.values().iterator().next()); } CompositeHealthIndicator composite = new CompositeHealthIndicator( this.healthAggregator); for (Map.Entry<String, S> entry : beans.entrySet()) { composite.addHealthIndicator(entry.getKey(), createHealthIndicator(entry.getValue())); } return composite; } @SuppressWarnings("unchecked") protected H createHealthIndicator(S source) { Class<?>[] generics = ResolvableType .forClass(CompositeHealthIndicatorConfiguration.class, getClass()) .resolveGenerics(); Class<H> indicatorClass = (Class<H>) generics[0]; Class<S> sourceClass = (Class<S>) generics[1]; try { return indicatorClass.getConstructor(sourceClass).newInstance(source); } catch (Exception ex) { throw new IllegalStateException("Unable to create indicator " + indicatorClass + " for source " + sourceClass, ex); } }}上方一系列的操作之后,其实就是搞出了一个RabbitMQ的 HealthIndicator 实现类,而负责检查RabbitMQ健康不健康也是这个类来负责的。由此我们可以想象到如果当前环境存在MySQL、Redis、ES等情况应该也是这么个操作
那么接下来无非就是当有调用方访问如下地址时,分别调用整个系统的所有的 HealthIndicator 的实现类的 health 方法即可了
http://ip:port/actuator/health
上边说的这个操作过程就在类 HealthEndpointAutoConfiguration 中,这个配置类同样也是在 spring.factories 文件中引入的
@Configuration@EnableConfigurationProperties({HealthEndpointProperties.class, HealthIndicatorProperties.class})@AutoConfigureAfter({HealthIndicatorAutoConfiguration.class})@Import({HealthEndpointConfiguration.class, HealthEndpointWebExtensionConfiguration.class})public class HealthEndpointAutoConfiguration { public HealthEndpointAutoConfiguration() { }}这里重点的地方在于引入的 HealthEndpointConfiguration 这个类
@Configurationclass HealthEndpointConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) { return new HealthEndpoint(HealthIndicatorBeansComposite.get(applicationContext)); }}这个类只是构建了一个类 HealthEndpoint ,这个类我们可以理解为一个SpringMVC的Controller,也就是处理如下请求的
http://ip:port/actuator/health那么首先看一下它的构造方法传入的是个啥对象吧
public static HealthIndicator get(ApplicationContext applicationContext) { HealthAggregator healthAggregator = getHealthAggregator(applicationContext); Map<String, HealthIndicator> indicators = new LinkedHashMap<>(); indicators.putAll(applicationContext.getBeansOfType(HealthIndicator.class)); if (ClassUtils.isPresent("reactor.core.publisher.Flux", null)) { new ReactiveHealthIndicators().get(applicationContext) .forEach(indicators::putIfAbsent); } CompositeHealthIndicatorFactory factory = new CompositeHealthIndicatorFactory(); return factory.createHealthIndicator(healthAggregator, indicators); }跟我们想象中的一样,就是通过Spring容器获取所有的 HealthIndicator 接口的实现类,我这里只有几个默认的和RabbitMQ
然后都放入了其中一个聚合的实现类 CompositeHealthIndicator 中
既然 HealthEndpoint构建好了,那么只剩下最后一步处理请求了
@Endpoint(id = "health")public class HealthEndpoint { private final HealthIndicator healthIndicator; @ReadOperation public Health health() { return this.healthIndicator.health(); }}刚刚我们知道,这个类是通过 CompositeHealthIndicator 构建的,所以 health 方法的实现就在这个类中
public Health health() { Map<String, Health> healths = new LinkedHashMap<>(); for (Map.Entry<String, HealthIndicator> entry : this.indicators.entrySet()) { //循环调用 healths.put(entry.getKey(), entry.getValue().health()); } //对结果集排序 return this.healthAggregator.aggregate(healths); }至此SpringBoot的健康检查实现原理全部解析完成
以上就是详解SpringBoot健康检查的实现原理的详细内容,更多关于SpringBoot健康检查实现原理的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
概述在使用SpringBoot的时候我们经常使用actuator,健康检查,bus中使用/refresh等。这里记录如何使用注解的方式自定义Endpoint。可
健康检查常用于判断一个应用程序能否对request请求进行响应,ASP.NetCore2.2中引入了健康检查中间件用于报告应用程序的健康状态。ASP.NetCo
Intro健康检查可以帮助我们知道应用的当前状态是不是处于良好状态,现在无论是docker还是k8s还是现在大多数的服务注册发现大多都提供了健康检查机制来检测应
严格来说,nginx自带是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的ngx_http_proxy_module模块和ngx_http_upst
伴随着医药学的发展,常规体检在大家的日常生活愈来愈关键。尤其是是中老年,按时做一个全身检查十分关键。健康检查的目地是在身心健康群体中,根据体检出现异常临床症状,