springboot的HealthAggregator

##序 对于系统服务的监控,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

转载于:https://my.oschina.net/go4it/blog/832077

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值