我是靠谱客的博主 沉默荷花,最近开发中收集的这篇文章主要介绍SpringCloud Nacos 心跳机制和服务健康检查源码解析1 客户端心跳机制2 服务端健康检查,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1 客户端心跳机制

1.1 客户端注册源码流程

https://blog.csdn.net/qq_34125999/article/details/117566523

1.2 NacosNamingService

1.2.1 注册服务方法

	@Override
    public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
    	
        NamingUtils.checkInstanceIsLegal(instance);
        //创建group@@servciceName
        String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
        //如果当前实例是临时实例(默认是临时实例)
        if (instance.isEphemeral()) {
	        // 创建心跳信息
            BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
            //beanReactor添加心跳信息
            beatReactor.addBeatInfo(groupedServiceName, beatInfo);
        }
        //发送请求向nacos注册服务
        serverProxy.registerService(groupedServiceName, groupName, instance);
    }

1.3 BeatReactor

1.3.1 buildBeatInfo

  public BeatInfo buildBeatInfo(String groupedServiceName, Instance instance) {
        //创建心跳对象
        BeatInfo beatInfo = new BeatInfo();
        //封装心跳信息
        beatInfo.setServiceName(groupedServiceName);
        beatInfo.setIp(instance.getIp());
        beatInfo.setPort(instance.getPort());
        beatInfo.setCluster(instance.getClusterName());
        beatInfo.setWeight(instance.getWeight());
        beatInfo.setMetadata(instance.getMetadata());
        beatInfo.setScheduled(false);
        /**
         * 心跳间隔默认为5秒
         */
        beatInfo.setPeriod(instance.getInstanceHeartBeatInterval());
        return beatInfo;
    }

在这里插入图片描述

1.3.2 addBeatInfo

在这里插入图片描述

1.3.3 BeatTask

描述: 查看 BeatTask 的run()方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 服务端处理心跳

描述: 查看接口。
在这里插入图片描述
在这里插入图片描述
描述: 异步处理请求。
在这里插入图片描述
****
描述: 查看异步任务ClientBeatProcessor,run方法。

 @Override
    public void run() {
        //找到当前服务
        Service service = this.service;
        if (Loggers.EVT_LOG.isDebugEnabled()) {
            Loggers.EVT_LOG.debug("[CLIENT-BEAT] processing beat: {}", rsInfo.toString());
        }
        //获取相关信息
        String ip = rsInfo.getIp();
        String clusterName = rsInfo.getCluster();
        int port = rsInfo.getPort();
        Cluster cluster = service.getClusterMap().get(clusterName);
        List<Instance> instances = cluster.allIPs(true);
            
        //遍历找到注册心跳的服务
        for (Instance instance : instances) {
            
            //比对ip、port
            if (instance.getIp().equals(ip) && instance.getPort() == port) {
                if (Loggers.EVT_LOG.isDebugEnabled()) {
                    Loggers.EVT_LOG.debug("[CLIENT-BEAT] refresh beat: {}", rsInfo.toString());
                }
                
                /**
                 * 设置心跳
                 */   
                instance.setLastBeat(System.currentTimeMillis());
                
                //如果当前服务没被标记并且不健康,更新当前服务状态
                if (!instance.isMarked()) {
                    if (!instance.isHealthy()) {
                        instance.setHealthy(true);
                        Loggers.EVT_LOG
                                .info("service: {} {POS} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: client beat ok",
                                        cluster.getService().getName(), ip, port, cluster.getName(),
                                        UtilsAndCommons.LOCALHOST_SITE);
                        getPushService().serviceChanged(service);
                    }
                }
            }
        }
    }

2 服务端健康检查

2.1 服务端注册nacos

https://blog.csdn.net/qq_34125999/article/details/117676950

2.2 Service

描述: 当服务注册时,会执行Service init方法,当前方法会异步开启注册服务健康监测。
在这里插入图片描述

2.3 HealthCheckReactor

描述: scheduleCheck方法,会异步提交ClientBeatCheckTask任务,延迟5秒后执行,并且每隔5秒执行。

 public static void scheduleCheck(ClientBeatCheckTask task) {
        futureMap.putIfAbsent(task.taskKey(), GlobalExecutor.scheduleNamingHealth(task, 5000, 5000, TimeUnit.MILLISECONDS));
    }

2.4 ClientBeatCheckTask

描述: 查看异步执行任务 run方法。

@Override
    public void run() {
        try {
            if (!getDistroMapper().responsible(service.getName())) {
                return;
            }

            if (!getSwitchDomain().isHealthCheckEnabled()) {
                return;
            }
            
            //获取服务所有Instance
            List<Instance> instances = service.allIPs(true);

            // first set health status of instances:
            //第一次,遍历所有服务
            for (Instance instance : instances) {
                //如果当前时间减去服务上次注册时间大于15秒
                if (System.currentTimeMillis() - instance.getLastBeat() > instance.getInstanceHeartBeatTimeOut()) {
                    //如果服务没被标记并且服务是健康的那么设置服务为非健康状态
                    if (!instance.isMarked()) {
                        if (instance.isHealthy()) {
                            instance.setHealthy(false);
                            Loggers.EVT_LOG
                                    .info("{POS} {IP-DISABLED} valid: {}:{}@{}@{}, region: {}, msg: client timeout after {}, last beat: {}",
                                            instance.getIp(), instance.getPort(), instance.getClusterName(),
                                            service.getName(), UtilsAndCommons.LOCALHOST_SITE,
                                            instance.getInstanceHeartBeatTimeOut(), instance.getLastBeat());
                            getPushService().serviceChanged(service);
                            ApplicationUtils.publishEvent(new InstanceHeartbeatTimeoutEvent(this, instance));
                        }
                    }
                }
            }

            if (!getGlobalConfig().isExpireInstance()) {
                return;
            }
            
            //第二次遍历所有服务
            // then remove obsolete instances:
            for (Instance instance : instances) {

                if (instance.isMarked()) {
                    continue;
                }
                //如果当前时间减去服务上次心跳时间大于30秒,那么当前服务
                if (System.currentTimeMillis() - instance.getLastBeat() > instance.getIpDeleteTimeout()) {
                    // delete instance
                    Loggers.SRV_LOG.info("[AUTO-DELETE-IP] service: {}, ip: {}", service.getName(),
                            JacksonUtils.toJson(instance));
                    //删除逻辑,调取nacos api进行服务删除【自己调自己】
                    deleteIp(instance);
                }
            }

        } catch (Exception e) {
            Loggers.SRV_LOG.warn("Exception while processing client beat time out.", e);
        }

    }

最后

以上就是沉默荷花为你收集整理的SpringCloud Nacos 心跳机制和服务健康检查源码解析1 客户端心跳机制2 服务端健康检查的全部内容,希望文章能够帮你解决SpringCloud Nacos 心跳机制和服务健康检查源码解析1 客户端心跳机制2 服务端健康检查所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部