All Downloads are FREE. Search and download functionalities are using the official Maven repository.

club.zhcs.lina.starter.monitor.health.ChainHealthIndicator Maven / Gradle / Ivy

There is a newer version: 3.3.4
Show newest version
package club.zhcs.lina.starter.monitor.health;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.nutz.lang.Lang;
import org.nutz.lang.Stopwatch;
import org.nutz.lang.Tasks;
import org.nutz.lang.Times;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;

import club.zhcs.lina.starter.monitor.MonitorConfigurationProperties.Chain.Service;
import club.zhcs.lina.starter.monitor.health.HealthChecker.ServiceHealth;
import lombok.RequiredArgsConstructor;

/**
 * 
 * @author Kerbores([email protected])
 *
 */
@RequiredArgsConstructor
public class ChainHealthIndicator implements HealthIndicator {

    private final List services;
    private final long interval;
    private final HealthChecker healthChecker;
    List healths;

    Log logger = Logs.get();

    @PostConstruct
    public void init() {
        // 定时检查链路可用性
        Tasks.scheduleAtFixedRate(this::healthCheckTask, Times.now(), interval, TimeUnit.SECONDS);
    }

    /**
     * 执行健康检查
     */
    public void healthCheckTask() {
        try {
            CountDownLatch countDownLatch = new CountDownLatch(services.size());
            healths = Lang.list();
            Stopwatch watch = Stopwatch.begin();
            logger.debugf("执行健康检测开始: %s", Times.format("yyyy-MM-dd HH:mm:ss", Times.now()));
            if (Lang.isNotEmpty(services)) {
                services.stream().forEach(service -> new Thread(() -> healths.add(checkService(service))).start());
            }
            countDownLatch.await();
            watch.stop();
            logger.debugf("执行健康检测结束: %s 耗时 %d 毫秒", Times.format("yyyy-MM-dd HH:mm:ss", Times.now()), watch.du());
        }
        catch (InterruptedException e) {
            logger.error(e);
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 单个接口的监控检查
     * 
     * @param service
     * @return
     */
    private ServiceHealth checkService(Service service) {
        return healthChecker.check(service);
    }

    @Override
    public Health health() {
        while (!services.isEmpty() && healths.isEmpty()) {// 如果检测的时候正好在跑且正好情况,那么稍等一下
            try {
                Thread.sleep(20);// 20ms
            }
            catch (InterruptedException e) {
                logger.error(e);
                Thread.currentThread().interrupt();
            }
        }
        org.springframework.boot.actuate.health.Health.Builder builder = Health
                                                                               .status(healths.stream()
                                                                                              .allMatch(h -> h.getStatus() == Status.UP) ? Status.UP
                                                                                                                                         : Status.DOWN);
        healths.stream()
               .forEach(h -> builder.withDetail(h.getService(),
                                                NutMap.NEW().addv("status", h.getStatus().getCode()).addv("time", h.getTime())));
        return builder.build();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy