聊聊nacos的HealthCheckCommon

本文主要研究一下nacos的HealthCheckCommon

HealthCheckCommon

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckCommon.java

@Component
public class HealthCheckCommon {

    @Autowired
    private DistroMapper distroMapper;

    @Autowired
    private SwitchDomain switchDomain;

    @Autowired
    private ServerListManager serverListManager;

    @Autowired
    private PushService pushService;

    private static LinkedBlockingDeque<HealthCheckResult> healthCheckResults = new LinkedBlockingDeque<>(1024 * 128);

    private static ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setDaemon(true);
            thread.setName("com.taobao.health-check.notifier");
            return thread;
        }
    });


    public void init() {
        executorService.schedule(new Runnable() {
            @Override
            public void run() {
                List list = Arrays.asList(healthCheckResults.toArray());
                healthCheckResults.clear();

                List<Server> sameSiteServers = serverListManager.getServers();

                if (sameSiteServers == null || sameSiteServers.size() <= 0) {
                    return;
                }

                for (Server server : sameSiteServers) {
                    if (server.getKey().equals(NetUtils.localServer())) {
                        continue;
                    }
                    Map<String, String> params = new HashMap<>(10);
                    params.put("result", JSON.toJSONString(list));
                    if (Loggers.SRV_LOG.isDebugEnabled()) {
                        Loggers.SRV_LOG.debug("[HEALTH-SYNC] server: {}, healthCheckResults: {}",
                            server, JSON.toJSONString(list));
                    }

                    HttpClient.HttpResult httpResult = HttpClient.httpPost("http://" + server.getKey()
                        + RunningConfig.getContextPath() + UtilsAndCommons.NACOS_NAMING_CONTEXT
                        + "/api/healthCheckResult", null, params);

                    if (httpResult.code != HttpURLConnection.HTTP_OK) {
                        Loggers.EVT_LOG.warn("[HEALTH-CHECK-SYNC] failed to send result to {}, result: {}",
                            server, JSON.toJSONString(list));
                    }

                }

            }
        }, 500, TimeUnit.MILLISECONDS);
    }

    //......

    public void reEvaluateCheckRT(long checkRT, HealthCheckTask task, SwitchDomain.HealthParams params) {
    	//......
    }

    public void checkOK(Instance ip, HealthCheckTask task, String msg) {
    	//......
    }

    public void checkFail(Instance ip, HealthCheckTask task, String msg) {
    	//......
    }

    public void checkFailNow(Instance ip, HealthCheckTask task, String msg) {
    	//......
    }

    //......
}
  • HealthCheckCommon的init方法注册了一个延时任务,往其他server同步healthCheckResults;它主要提供了reEvaluateCheckRT、checkOK、checkFail、checkFailNow方法

reEvaluateCheckRT

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckCommon.java

    public void reEvaluateCheckRT(long checkRT, HealthCheckTask task, SwitchDomain.HealthParams params) {
        task.setCheckRTLast(checkRT);

        if (checkRT > task.getCheckRTWorst()) {
            task.setCheckRTWorst(checkRT);
        }

        if (checkRT < task.getCheckRTBest()) {
            task.setCheckRTBest(checkRT);
        }

        checkRT = (long) ((params.getFactor() * task.getCheckRTNormalized()) + (1 - params.getFactor()) * checkRT);

        if (checkRT > params.getMax()) {
            checkRT = params.getMax();
        }

        if (checkRT < params.getMin()) {
            checkRT = params.getMin();
        }

        task.setCheckRTNormalized(checkRT);
    }
  • reEvaluateCheckRT方法首先更新checkRTLast,然后判断是否更新checkRTWorst、checkRTBest,之后根据factor及checkRTNormalized参数重置checkRT,最后更新checkRTNormalized

checkOK

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckCommon.java

public void checkOK(Instance ip, HealthCheckTask task, String msg) {
    Cluster cluster = task.getCluster();

    try {
        if (!ip.isHealthy() || !ip.isMockValid()) {
            if (ip.getOKCount().incrementAndGet() >= switchDomain.getCheckTimes()) {
                if (distroMapper.responsible(cluster, ip)) {
                    ip.setHealthy(true);
                    ip.setMockValid(true);

                    Service service = cluster.getService();
                    service.setLastModifiedMillis(System.currentTimeMillis());
                    pushService.serviceChanged(service);
                    addResult(new HealthCheckResult(service.getName(), ip));

                    Loggers.EVT_LOG.info("serviceName: {} {POS} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: {}",
                        cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), UtilsAndCommons.LOCALHOST_SITE, msg);
                } else {
                    if (!ip.isMockValid()) {
                        ip.setMockValid(true);
                        Loggers.EVT_LOG.info("serviceName: {} {PROBE} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: {}",
                            cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), UtilsAndCommons.LOCALHOST_SITE, msg);
                    }
                }
            } else {
                Loggers.EVT_LOG.info("serviceName: {} {OTHER} {IP-ENABLED} pre-valid: {}:{}@{} in {}, msg: {}",
                    cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), ip.getOKCount(), msg);
            }
        }
    } catch (Throwable t) {
        Loggers.SRV_LOG.error("[CHECK-OK] error when close check task.", t);
    }

    ip.getFailCount().set(0);
    ip.setBeingChecked(false);
}
  • checkOK对于非healthy或者mockValid的instance会设置其为healthy及mockValid,然后通过pushService.serviceChanged发布变更事件,并添加HealthCheckResult到healthCheckResults中

checkFail

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckCommon.java

   public void checkFail(Instance ip, HealthCheckTask task, String msg) {
        Cluster cluster = task.getCluster();

        try {
            if (ip.isHealthy() || ip.isMockValid()) {
                if (ip.getFailCount().incrementAndGet() >= switchDomain.getCheckTimes()) {
                    if (distroMapper.responsible(cluster, ip)) {
                        ip.setHealthy(false);
                        ip.setMockValid(false);

                        Service service = cluster.getService();
                        service.setLastModifiedMillis(System.currentTimeMillis());
                        addResult(new HealthCheckResult(service.getName(), ip));

                        pushService.serviceChanged(service);

                        Loggers.EVT_LOG.info("serviceName: {} {POS} {IP-DISABLED} invalid: {}:{}@{}, region: {}, msg: {}",
                            cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), UtilsAndCommons.LOCALHOST_SITE, msg);
                    } else {
                        Loggers.EVT_LOG.info("serviceName: {} {PROBE} {IP-DISABLED} invalid: {}:{}@{}, region: {}, msg: {}",
                            cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), UtilsAndCommons.LOCALHOST_SITE, msg);
                    }

                } else {
                    Loggers.EVT_LOG.info("serviceName: {} {OTHER} {IP-DISABLED} pre-invalid: {}:{}@{} in {}, msg: {}",
                        cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), ip.getFailCount(), msg);
                }
            }
        } catch (Throwable t) {
            Loggers.SRV_LOG.error("[CHECK-FAIL] error when close check task.", t);
        }

        ip.getOKCount().set(0);

        ip.setBeingChecked(false);
    }
  • checkFail对于healthy或者mockValid的instance会设置其healthy及mockValid为false,然后通过pushService.serviceChanged发布变更事件,并添加HealthCheckResult到healthCheckResults中

checkFailNow

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckCommon.java

public void checkFailNow(Instance ip, HealthCheckTask task, String msg) {
Cluster cluster = task.getCluster();
try {
if (ip.isHealthy() || ip.isMockValid()) {
if (distroMapper.responsible(cluster, ip)) {
ip.setHealthy(false);
ip.setMockValid(false);

            Service service = cluster.getService();
            service.setLastModifiedMillis(System.currentTimeMillis());

            pushService.serviceChanged(service);
            addResult(new HealthCheckResult(service.getName(), ip));

            Loggers.EVT_LOG.info("serviceName: {} {POS} {IP-DISABLED} invalid-now: {}:{}@{}, region: {}, msg: {}",
                cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), UtilsAndCommons.LOCALHOST_SITE, msg);
        } else {
            if (ip.isMockValid()) {
                ip.setMockValid(false);
                Loggers.EVT_LOG.info("serviceName: {} {PROBE} {IP-DISABLED} invalid-now: {}:{}@{}, region: {}, msg: {}",
                    cluster.getService().getName(), ip.getIp(), ip.getPort(), cluster.getName(), UtilsAndCommons.LOCALHOST_SITE, msg);
            }

        }
    }
} catch (Throwable t) {
    Loggers.SRV_LOG.error("[CHECK-FAIL-NOW] error when close check task.", t);
}

ip.getOKCount().set(0);
ip.setBeingChecked(false);
 }
  • checkFailNow对于healthy或者mockValid的instance会设置其healthy及mockValid为false,然后通过pushService.serviceChanged发布变更事件,并添加HealthCheckResult到healthCheckResults中;与checkFail不同的是它对于非自己负责的instance会立马标记mockVlid为false

小结

HealthCheckCommon的init方法注册了一个延时任务,往其他server同步healthCheckResults;它主要提供了reEvaluateCheckRT、checkOK、checkFail、checkFailNow方法

doc

HealthCheckCommon

(想自学习编程的小伙伴请搜索圈T社区,更多行业相关资讯更有行业相关免费视频教程。完全免费哦!)

Nacos是一个非常强大的服务发现和配置中心,它不仅可以实现服务注册与发现,还可以作为配置中心来管理应用程序的配置信息。在Spring Cloud中,我们可以使用Nacos作为配置中心,实现应用程序的动态配置。 关于Nacos配置不会动态刷新的问题,一般有以下几种原因: 1. 缓存问题 Nacos配置中心默认会有一层本地缓存,如果配置没有发生变化,客户端就不会刷新配置。可以通过设置配置缓存时间或者禁用缓存来解决该问题。 2. 配置监听器未开启 Nacos配置中心支持配置监听器,在配置发生变化时会自动通知客户端进行更新。如果监听器未开启,就无法实现动态刷新配置。可以通过在bootstrap.yml或bootstrap.properties中添加如下配置开启监听器: ``` spring.cloud.nacos.config.listener.enabled=true ``` 3. 配置文件未被监听 如果配置文件未被监听,即使监听器已经开启也无法实现动态刷新配置。在bootstrap.yml或bootstrap.properties中添加如下配置,即可监听指定的配置文件: ``` spring.cloud.nacos.config.file-extension=properties,yaml,yml spring.cloud.nacos.config.group=DEFAULT_GROUP spring.cloud.nacos.config.prefix=${spring.application.name} ``` 其中,file-extension指定配置文件的扩展名,group指定配置分组,默认为DEFAULT_GROUP,prefix指定配置文件的前缀,默认为应用程序的名称。 综上所述,如果遇到Nacos配置不会动态刷新的问题,可以先检查缓存设置、监听器和配置文件是否正确配置。如果仍无法解决问题,可以尝试升级Nacos版本或者进行调试排查。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值