当前位置: 首页 > news >正文

spring-boot-actuator-Health原理

说明

在容器化部署下,如何判断服务是否健康通过 curl  127.0.0.1:8080/actuator/health检查 是否是健康状态

使用示例以sentinel为例

实现抽象类

public class SentinelHealthIndicator extends AbstractHealthIndicator {private DefaultListableBeanFactory beanFactory;private SentinelProperties sentinelProperties;public SentinelHealthIndicator(DefaultListableBeanFactory beanFactory,SentinelProperties sentinelProperties) {this.beanFactory = beanFactory;this.sentinelProperties = sentinelProperties;}@Overrideprotected void doHealthCheck(Health.Builder builder) throws Exception {Map<String, Object> detailMap = new HashMap<>();// If sentinel isn't enabled, set the status up and set the enabled to false in// detailif (!sentinelProperties.isEnabled()) {detailMap.put("enabled", false);builder.up().withDetails(detailMap);return;}detailMap.put("enabled", true);// Check health of Dashboardboolean dashboardUp = true;List<Tuple2<String, Integer>> consoleServerList = TransportConfig.getConsoleServerList();if (CollectionUtils.isEmpty(consoleServerList)) {// If Dashboard isn't configured, it's OK and mark the status of Dashboard// with UNKNOWN.detailMap.put("dashboard",new Status(Status.UNKNOWN.getCode(), "dashboard isn't configured"));}else {// If Dashboard is configured, send a heartbeat message to it and check the// resultHeartbeatSender heartbeatSender = HeartbeatSenderProvider.getHeartbeatSender();boolean result = heartbeatSender.sendHeartbeat();if (result) {detailMap.put("dashboard", Status.UP);}else {// If failed to send heartbeat message, means that the Dashboard is DOWNdashboardUp = false;detailMap.put("dashboard",new Status(Status.UNKNOWN.getCode(), String.format("the dashboard servers [%s] one of them can't be connected",consoleServerList)));}}// Check health of DataSourceboolean dataSourceUp = true;Map<String, Object> dataSourceDetailMap = new HashMap<>();detailMap.put("dataSource", dataSourceDetailMap);// Get all DataSources and each call loadConfig to check if it's OK// If no Exception thrown, it's OK// Note:// Even if the dynamic config center is down, the loadConfig() might return// successfully// e.g. for Nacos client, it might retrieve from the local cache)// But in most circumstances it's okayMap<String, AbstractDataSource> dataSourceMap = beanFactory.getBeansOfType(AbstractDataSource.class);for (Map.Entry<String, AbstractDataSource> dataSourceMapEntry : dataSourceMap.entrySet()) {String dataSourceBeanName = dataSourceMapEntry.getKey();AbstractDataSource dataSource = dataSourceMapEntry.getValue();try {dataSource.loadConfig();dataSourceDetailMap.put(dataSourceBeanName, Status.UP);}catch (Exception e) {// If one DataSource failed to loadConfig, means that the DataSource is// DOWNdataSourceUp = false;dataSourceDetailMap.put(dataSourceBeanName,new Status(Status.UNKNOWN.getCode(), e.getMessage()));}}// If Dashboard and DataSource are both OK, the health status is UPif (dashboardUp && dataSourceUp) {builder.up().withDetails(detailMap);}else {builder.unknown().withDetails(detailMap);}}}
View Code

注入容器

        @Bean@ConditionalOnMissingBean@ConditionalOnEnabledHealthIndicator("sentinel") //management.health.sentinel.enabled=false 可禁用public SentinelHealthIndicator sentinelHealthIndicator(DefaultListableBeanFactory beanFactory,SentinelProperties sentinelProperties) {return new SentinelHealthIndicator(beanFactory, sentinelProperties);}

访问CURL端点

image

 初始化原理

1、初始化HealthIndicatorRegistry

org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration#healthIndicatorRegistry

 @Bean@ConditionalOnMissingBean({HealthIndicatorRegistry.class})public HealthIndicatorRegistry healthIndicatorRegistry(ApplicationContext applicationContext) {//内部会从容器获取HealthIndicator实现类 里面就有我们的sentinel实现类return HealthIndicatorRegistryBeans.get(applicationContext);}

 

2、org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorRegistryBeans#get

    public static HealthIndicatorRegistry get(ApplicationContext applicationContext) {Map<String, HealthIndicator> indicators = new LinkedHashMap();//从容器获取indicators.putAll(applicationContext.getBeansOfType(HealthIndicator.class));if (ClassUtils.isPresent("reactor.core.publisher.Flux", (ClassLoader)null)) {(new ReactiveHealthIndicators()).get(applicationContext).forEach(indicators::putIfAbsent);}HealthIndicatorRegistryFactory factory = new HealthIndicatorRegistryFactory();//构建 HealthIndicatorRegistryreturn factory.createHealthIndicatorRegistry(indicators);}

3、返回含有所有health健康检查的 registry

     public HealthIndicatorRegistry createHealthIndicatorRegistry(Map<String, HealthIndicator> healthIndicators) {Assert.notNull(healthIndicators, "HealthIndicators must not be null");//初始化return initialize(new DefaultHealthIndicatorRegistry(), healthIndicators);}protected <T extends HealthIndicatorRegistry> T initialize(T registry,Map<String, HealthIndicator> healthIndicators) {for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {//这里主要是获取bean的名字 截取掉 如 sentinelHealthIndicator  截取掉HealthIndicator  name为sentinelString name = this.healthIndicatorNameFactory.apply(entry.getKey());registry.register(name, entry.getValue());}return registry;}

执行原理

1、actor模式会在Spring MVC注册一个mappring入口为

org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler#handle

->

org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.ServletWebOperationAdapter#handle

->

org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation#invoke

->

org.springframework.boot.actuate.health.HealthEndpointWebExtension#health

->

org.springframework.boot.actuate.health.HealthEndpointWebExtension#health

     @ReadOperationpublic WebEndpointResponse<Health> health(SecurityContext securityContext) {//内部就是从 初始化的registry遍历所有的处理器获取检查结果return this.responseMapper.map(this.delegate.health(), securityContext);}

2、org.springframework.boot.actuate.health.HealthEndpoint#health

image

 3、org.springframework.boot.actuate.health.CompositeHealthIndicator#health

    @Overridepublic Health health() {Map<String, Health> healths = new LinkedHashMap<>();for (Map.Entry<String, HealthIndicator> entry : this.registry.getAll().entrySet()) {//遍历执行 获取结果
            healths.put(entry.getKey(), entry.getValue().health());}//进行聚合返回return this.aggregator.aggregate(healths);}

 

http://www.jsqmd.com/news/31286/

相关文章:

  • 2025年广州防霉检测机构权威推荐榜单:除螨检测/除臭效果测试/输配水设备检测源头机构精选
  • 2025年钣金机箱外壳加工厂家权威推荐榜单:钣金壳体/变频器钣金壳体/钣金加工壳体源头厂家精选
  • 从零到一:我的开源AI商业化实战之路
  • 机器学习 BASEML到底是什么
  • 体育馆游泳卡押金原路退回,安心无忧—东方仙盟 - 指南
  • DesignSpark Mechanical (DSM)输入用户名密码提示在注册过程中发生错误
  • 字段(辨析:字段、对象、属性和方法在 JavaScript 中的关系)
  • P14364 [CSP-S 2025] 员工招聘 / employ 笔记
  • Spring boot 使用虚拟线程示例
  • 微算法科技(NASDAQ MLGO):以隐私计算区块链筑牢多方安全计算(MPC)安全防线
  • 怎么把idea的目录结构,以文本形式输出?——idea使用tree
  • 2025年11月沼气直燃厂家综合评测:徐州海德测控技术有限公司领跑
  • 微信小程序初始配置
  • python爬虫scrapy框架使用 - 教程
  • 2025年塑烧板除尘器源头厂家权威推荐榜单:耐高温除尘器/防爆除尘器/不锈钢除尘器源头厂家精选
  • 2025年剪叉升降平台供应商权威推荐榜单:车载剪叉式升降平台/移动剪叉式升降平台车/轨道升降平台源头厂家精选
  • 第180天:横向移动篇入口切换SMB共享WMI管道DCOM组件Impacket套件CS插件
  • 2025年11月沼气直燃品牌/品牌排名前十:技术实力对比与总结
  • 高效学习方式——知识关联性
  • 基于时间的ACL - 教程
  • 2025年云南做楼体灯光亮化服务商权威推荐榜单:云南做酒店灯光亮化/云南做居民楼灯光亮化/云南做写字楼灯光亮化服务商精选
  • 信息系统方案的范围管理(12345智慧政务)
  • [Python刷题记录]-三数之和-双指针-中等
  • Serilog日志库简单实践(一):控制台与调试Sinks(.NET 8)汇报总结
  • WPF实现组件拖动(Canvas)
  • 2025 年最新测控终端厂家推荐:符合国标 + 数据透传技术,靠谱企业深度测评报告4G 测控终端/远程测控终端/物联网测控终端/测控终端 RTU 公司推荐
  • 使用Node.js开发MCP服务器入门总结
  • 2025年菊花种苗生产厂家权威推荐榜单:菊花造型/菊花花坛/菊花种苗基地源头厂家精选
  • 2025年低噪音冷却塔实力厂家权威推荐榜单:工业冷却塔/防腐蚀冷却塔/冷却塔填料源头厂家精选
  • React系列教程:2. 定义一个组件