文档章节

springboot的HealthAggregator

go4it
 go4it
发布于 2017/02/05 20:30
字数 675
阅读 22
收藏 0

##序 对于系统服务的监控,tcp层通常是用heartbeat来进行,最简单的比如ping-pong。对于http层,来说springboot的actuator内置了/health的endpoint,很方便地规范了每个服务的健康状况的api,而且HealthIndicator可以自己去扩展,增加相关依赖服务的健康状态,非常灵活方便而且可扩展。

##/health实例

{
  "status": "UP",
  "custom": {
    "status": "UNKNOWN",
    "custom": {
      "status": "UNKNOWN",
      "msg": "mock down to test aggregator"
    }
  },
  "diskSpace": {
    "status": "UP",
    "total": 249779191808,
    "free": 57925111808,
    "threshold": 10485760
  }
}

##status枚举

	/**
	 * Convenient constant value representing unknown state.
	 */
	public static final Status UNKNOWN = new Status("UNKNOWN");

	/**
	 * Convenient constant value representing up state.
	 */
	public static final Status UP = new Status("UP");

	/**
	 * Convenient constant value representing down state.
	 */
	public static final Status DOWN = new Status("DOWN");

	/**
	 * Convenient constant value representing out-of-service state.
	 */
	public static final Status OUT_OF_SERVICE = new Status("OUT_OF_SERVICE");

##/health的两个贴心点 对于多个HealthIndicator的status,spring boot默认对其进行aggregrate,然后计算最顶层的status字段的值,而且对于status是DOWN或者是OUT_OF_SERVICE的,返回的http的状态码是503,这对于应用监控系统来说真是大大的贴心啊,再总结一下:

  • 自动聚合多个HealthIndicator的status
  • 对于status是DOWN或者是OUT_OF_SERVICE的,返回503

这样应用监控系统一来就无需去解析返回结果,直接根据http的状态码就可以判断了,非常方便,太省心了有没有。

##HealthAggregator

/**
 * Base {@link HealthAggregator} implementation to allow subclasses to focus on
 * aggregating the {@link Status} instances and not deal with contextual details etc.
 *
 * @author Christian Dupuis
 * @author Vedran Pavic
 * @since 1.1.0
 */
public abstract class AbstractHealthAggregator implements HealthAggregator {

	@Override
	public final Health aggregate(Map<String, Health> healths) {
		List<Status> statusCandidates = new ArrayList<Status>();
		for (Map.Entry<String, Health> entry : healths.entrySet()) {
			statusCandidates.add(entry.getValue().getStatus());
		}
		Status status = aggregateStatus(statusCandidates);
		Map<String, Object> details = aggregateDetails(healths);
		return new Health.Builder(status, details).build();
	}

	/**
	 * Return the single 'aggregate' status that should be used from the specified
	 * candidates.
	 * @param candidates the candidates
	 * @return a single status
	 */
	protected abstract Status aggregateStatus(List<Status> candidates);

	/**
	 * Return the map of 'aggregate' details that should be used from the specified
	 * healths.
	 * @param healths the health instances to aggregate
	 * @return a map of details
	 * @since 1.3.1
	 */
	protected Map<String, Object> aggregateDetails(Map<String, Health> healths) {
		return new LinkedHashMap<String, Object>(healths);
	}

}

##OrderedHealthAggregator#aggregateStatus

	@Override
	protected Status aggregateStatus(List<Status> candidates) {
		// Only sort those status instances that we know about
		List<Status> filteredCandidates = new ArrayList<Status>();
		for (Status candidate : candidates) {
			if (this.statusOrder.contains(candidate.getCode())) {
				filteredCandidates.add(candidate);
			}
		}
		// If no status is given return UNKNOWN
		if (filteredCandidates.isEmpty()) {
			return Status.UNKNOWN;
		}
		// Sort given Status instances by configured order
		Collections.sort(filteredCandidates, new StatusComparator(this.statusOrder));
		return filteredCandidates.get(0);
	}

可以看出是对status进行排序,然后取第一个的状态,其中statusOrder如下:

private List<String> statusOrder;

	/**
	 * Create a new {@link OrderedHealthAggregator} instance.
	 */
	public OrderedHealthAggregator() {
		setStatusOrder(Status.DOWN, Status.OUT_OF_SERVICE, Status.UP, Status.UNKNOWN);
	}

排序方法

/**
	 * {@link Comparator} used to order {@link Status}.
	 */
	private class StatusComparator implements Comparator<Status> {

		private final List<String> statusOrder;

		StatusComparator(List<String> statusOrder) {
			this.statusOrder = statusOrder;
		}

		@Override
		public int compare(Status s1, Status s2) {
			int i1 = this.statusOrder.indexOf(s1.getCode());
			int i2 = this.statusOrder.indexOf(s2.getCode());
			return (i1 < i2 ? -1 : (i1 == i2 ? s1.getCode().compareTo(s2.getCode()) : 1));
		}

	}

即Status.DOWN, Status.OUT_OF_SERVICE, Status.UP, Status.UNKNOWN优先级依次递减。status中一旦有出现DOWN的情况,整体的status就是DOWN,依次类推。

##doc

© 著作权归作者所有

上一篇: curl记录响应时间
下一篇: Delivery Pipeline
go4it
粉丝 83
博文 1003
码字总数 967396
作品 0
深圳
私信 提问
恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年
2018/04/19
0
0
SpringBootBucket 2.0.4 发布,代号“傲娇的小二晶”

SpringBootBucket 自从1.0.0版本发布后就有好多人喜欢,目前码云上面star数量接近1.2k。上个月还收到了红薯签名的1000 star奖杯,这个我自己也觉得很惊讶。 由于SpringBoot 1.x官方将终止维护...

一刀
2018/09/16
1K
4
springboot情操陶冶-初识springboot

前言:springboot由于其轻便和去配置化等的特性已经被广泛应用,基于时代潮流以及不被鄙视,笔者于是开辟此篇开始认识springboot 前话 springboot是基于spring而开发的轻量级框架,所以在学习...

南柯问天
2018/07/24
0
0
springboot 详解 (六)servlet & scheduled & listener

---------------------------------------------------------------------------------------------------------------- springboot 详解 (一) helloworld 下载demo springboot 详解 (二)......

curiousby
2016/11/17
0
0
SpringBootBucket 1.0.0 发布,SprintBoot 全家桶

Spring Boot 现在已经成为Java 开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成。 本项目对目前Web开发中常用的各个技术,通过和SpringBoot的集成,并且对各种技术通过“一...

一刀
2018/03/05
7.3K
17

没有更多内容

加载失败,请刷新页面

加载更多

在Javascript中Eval函数的使用

【eval()函数】 JavaScript有许多小窍门来使编程更加容易。 其中之一就是eval()函数,这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。 举个小例子: var the_unevaled_ans...

花漾年华
刚刚
0
0
[日更-2019.5.22、23] Android 系统的分区和文件系统(二)--Android 文件系统中的文件

声明 Android系统中有很多分区,每个分区内的文件系统一般都不同的,使用ADB进入系统/目录下可发现挂载这很多的目录,不同的目录中可来自不同的分区及文件系统; 那么,就来分下这些目录里面...

小馬佩德罗
4分钟前
0
0
数组算法

/*数组的相关的算法操作:1、在数组中找最大值/最小值*/class Test11_FindMax{public static void main(String[] args){int[] array = {4,2,6,8,1};//在数组中找最大...

architect刘源源
52分钟前
2
0
okhttp3 以上版本在安卓9.0无法请求数据的解决方案

应用官方的说明:在 Android 6.0 中,我们取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始,默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。且Android P 限制了明文流量...

chenhongjiang
今天
11
0
简单示例:NodeJs连接mysql数据库

开篇引用网上的说法: 简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于...

李朝强
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部