zoukankan      html  css  js  c++  java
  • Springboot Actuator之五:Springboot中的HealthAggregator、新增自定义Status

    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
      }
    }

    health的Status枚举

    org.springframework.boot.actuate.health.Status.java

    @JsonInclude(Include.NON_EMPTY)
    public final class Status {
    
        /**
         * {@link Status} indicating that the component or subsystem is in an unknown state.
         */
        public static final Status UNKNOWN = new Status("UNKNOWN");
    
        /**
         * {@link Status} indicating that the component or subsystem is functioning as
         * expected.
         */
        public static final Status UP = new Status("UP");
    
        /**
         * {@link Status} indicating that the component or subsystem has suffered an
         * unexpected failure.
         */
        public static final Status DOWN = new Status("DOWN");
    
        /**
         * {@link Status} indicating that the component or subsystem has been taken out of
         * service and should not be used.
         */
        public static final Status OUT_OF_SERVICE = new Status("OUT_OF_SERVICE");

    对多个Status的聚合

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

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

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

    看看AbstractHealthAggregator.java的抽象类,其中对状态的聚合是abstract的。

    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);
        }
    
    } 

    自定义Status,以及对Status聚合逻辑的调整

    重写参考了OrderedHealthAggregator类,增加了 GIT_WARNING
    public class OrderedHealthAggregator extends AbstractHealthAggregator {
    
        private List<String> statusOrder;
        
        public static final Status GIT_WARNING = new Status("GIT_WARNING", "警告:config-server连不上gitlab,请及时处理.");
    
        /**
         * Create a new {@link OrderedHealthAggregator} instance.
         */
        public OrderedHealthAggregator() {
            setStatusOrder(Status.DOWN, Status.OUT_OF_SERVICE, GIT_WARNING,  Status.UP, Status.UNKNOWN);
        }
    
        /**
         * Set the ordering of the status.
         * @param statusOrder an ordered list of the status
         */
        public void setStatusOrder(Status... statusOrder) {
            String[] order = new String[statusOrder.length];
            for (int i = 0; i < statusOrder.length; i++) {
                order[i] = statusOrder[i].getCode();
            }
            setStatusOrder(Arrays.asList(order));
        }
    
        /**
         * Set the ordering of the status.
         * @param statusOrder an ordered list of the status codes
         */
        public void setStatusOrder(List<String> statusOrder) {
            Assert.notNull(statusOrder, "StatusOrder must not be null");
            this.statusOrder = statusOrder;
        }
    
        @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) {
                //只识别Status.DOWN, Status.OUT_OF_SERVICE, GIT_WARNING,  Status.UP, Status.UNKNOWN几种状态
                if (this.statusOrder.contains(candidate.getCode())) {
                    filteredCandidates.add(candidate);
                }
            }
            // If no status is given return UNKNOWN
            if (filteredCandidates.isEmpty()) {
                return Status.UNKNOWN;
            }
            //对多个结果状态的排序,按照各个状态在statusOrder集合中的位置排序
            Collections.sort(filteredCandidates, new StatusComparator(this.statusOrder));
            
            //返回排在最上面的那个状态值
            return filteredCandidates.get(0);
        }
    
        /**
         * {@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) {
                //对多个结果状态的排序,按照各个状态在statusOrder集合中的位置排序
                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, GIT_WARNING, Status.UP, Status.UNKNOWN优先级依次递减。status中一旦有出现DOWN的情况,整体的status就是DOWN,依次类推。

  • 相关阅读:
    [ARC080D] Prime Flip
    硬币游戏
    点分治
    OneInDark对众数的爱
    [CF838D] Airplane Arrangements
    网络流总结(转载)
    二分图最大权完美匹配(KM)
    网络流
    FWT
    FFT & NTT
  • 原文地址:https://www.cnblogs.com/duanxz/p/11276196.html
Copyright © 2011-2022 走看看