博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot的HealthAggregator
阅读量:5918 次
发布时间:2019-06-19

本文共 4426 字,大约阅读时间需要 14 分钟。

对于系统服务的监控,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
healths) { List
statusCandidates = new ArrayList
(); for (Map.Entry
entry : healths.entrySet()) { statusCandidates.add(entry.getValue().getStatus()); } Status status = aggregateStatus(statusCandidates); Map
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
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
aggregateDetails(Map
healths) { return new LinkedHashMap
(healths); }}

OrderedHealthAggregator#aggregateStatus

@Override    protected Status aggregateStatus(List
candidates) { // Only sort those status instances that we know about List
filteredCandidates = new ArrayList
(); 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
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
{ private final List
statusOrder; StatusComparator(List
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

转载地址:http://xcbvx.baihongyu.com/

你可能感兴趣的文章
利用InetAddress类确定特殊IP地址
查看>>
display的inline,block,inline-block
查看>>
查看linux端口占用情况
查看>>
Pig 读书笔记 + 工作总结(干货很多)
查看>>
10.Linux之用户管理
查看>>
Objective-C学习笔记 复合
查看>>
centos7 安装mysql5.6 以及部分优化
查看>>
计算两个时间(ZonedDateTime)相差分钟数
查看>>
haproxy的基本使用方法
查看>>
Visual Assist X 最有用的几个快捷键
查看>>
列出数据库中常用的锁及其应用场景
查看>>
Python3 OS 文件/目录方法 — 图 表 概 览
查看>>
RPC (远程过程调用)
查看>>
序列类型之元组14
查看>>
使用cocos3.0创建项目总结
查看>>
我的友情链接
查看>>
MySQL基础(2)
查看>>
fedora16 准备工作更新中。
查看>>
Spark算子:RDD键值转换操作(5)–leftOuterJoin、rightOuterJoin、subtractByKey
查看>>
我的友情链接
查看>>