nacos(三) 心跳检测原理

这篇文章主要针对nacos客户端的心跳检测。

  1. 在上一篇文章已提到注册服务的时候,碰到临时节点需要注册心跳检测
 	@Override
    public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {

        if (instance.isEphemeral()) {//临时节点, 配置心跳检测
            BeatInfo beatInfo = new BeatInfo();
            beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
            beatInfo.setIp(instance.getIp());
            beatInfo.setPort(instance.getPort());
            beatInfo.setCluster(instance.getClusterName());
            beatInfo.setWeight(instance.getWeight());
            beatInfo.setMetadata(instance.getMetadata());
            beatInfo.setScheduled(false);
            //配置心跳检测间隔, 默认5秒
            long instanceInterval = instance.getInstanceHeartBeatInterval();
            beatInfo.setPeriod(instanceInterval == 0 ? DEFAULT_HEART_BEAT_INTERVAL : instanceInterval);

            beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
        }

        serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
    }
  1. 心跳检测间隔是可以改变的, 我们可以进入instance.getInstanceHeartBeatInterval()方法看看nacos是如何获取的
  
 public long getInstanceHeartBeatInterval() {
 		//通过方法名都可以明白意思:根据key去获取检测间隔,如果没有,则选择默认值
        return getMetaDataByKeyWithDefault(PreservedMetadataKeys.HEART_BEAT_INTERVAL, Constants.DEFAULT_HEART_BEAT_INTERVAL);
    }
 
 //key 名称
 public static final String HEART_BEAT_INTERVAL = "preserved.heart.beat.interval";
 //默认值 5秒
 public static final long DEFAULT_HEART_BEAT_INTERVAL = TimeUnit.SECONDS.toMillis(5);
  1. 根据HEART_BEAT_INTERVAL常量,我们去application.yml设置自己想要的间隔时间
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        heart-beat-interval: 10

在这里插入图片描述
4. 我们继续往下走, 进入beatReactor.addBeatInfo()方法, 发现心跳检测主要是创建了一个定时任务, 我们看一下BeatTask里面做了什么

public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
        NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
        String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
        BeatInfo existBeat = null;
        //fix #1733
        if ((existBeat = dom2Beat.remove(key)) != null) {
            existBeat.setStopped(true);
        }
        //dom2Beat 是一个concurrenthashmap, 当nacos服务关闭时, 会用到它来销毁定时任务
        dom2Beat.put(key, beatInfo); 
        executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
        MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
    }
  1. 发现 BeatTask 实现 runnable接口,serverProxy.sendBeat发送心跳,发送完后,再创建一个定时任务,这个心跳检测就能一直不间断进行下去,直到nacos服务销毁
class BeatTask implements Runnable {

        BeatInfo beatInfo;

        public BeatTask(BeatInfo beatInfo) {
            this.beatInfo = beatInfo;
        }

        @Override
        public void run() {
            if (beatInfo.isStopped()) {
                return;
            }
            long result = serverProxy.sendBeat(beatInfo);
            long nextTime = result > 0 ? result : beatInfo.getPeriod();
            executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
        }
    }
  1. serverProxy.sendBeat(beatInfo)主要是调用nacos服务端的API, 至此心跳检测客服端流程走完。
public long sendBeat(BeatInfo beatInfo) {
        try {
            if (NAMING_LOGGER.isDebugEnabled()) {
                NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
            }
            Map<String, String> params = new HashMap<String, String>(4);
            params.put("beat", JSON.toJSONString(beatInfo));
            params.put(CommonParams.NAMESPACE_ID, namespaceId);
            params.put(CommonParams.SERVICE_NAME, beatInfo.getServiceName());
            String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, HttpMethod.PUT);
            JSONObject jsonObject = JSON.parseObject(result);

            if (jsonObject != null) {
                return jsonObject.getLong("clientBeatInterval");
            }
        } catch (Exception e) {
            NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: " + JSON.toJSONString(beatInfo), e);
        }
        return 0L;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nacos(全称为阿里巴巴的 'Naming and Configuration Service')是一个开源的动态服务发现、配置管理和服务管理平台。作为注册中心,Nacos原理主要包括以下几个方面: 1. 注册:服务提供者在启动时将自己的服务注册到Nacos服务器上,同时提供一些元数据,如IP地址、端口号、健康状态等。 2. 发现:服务消费者通过向Nacos服务器发送查询请求,获取可用的服务实例列表。Nacos支持多种服务发现方式,包括基于DNS的服务发现和基于HTTP/REST的服务发现。 3. 配置管理:Nacos提供了统一的配置管理功能,允许将应用程序的配置存储在Nacos服务器上,并且支持动态更新。应用程序可以通过监听配置变更事件来实时获取最新的配置信息。 4. 健康检查:Nacos通过定期向服务实例发送心跳检测保证其健康状态,并将不健康的实例从服务列表中剔除,以确保服务消费者只能获取到可用的服务实例。 5. 集群和负载均衡:Nacos支持多节点部署,可以构建高可用的集群环境。同时,Nacos还提供了负载均衡的功能,可以根据不同的负载均衡策略来分配请求到不同的服务实例。 总之,Nacos作为注册中心的原理是通过服务提供者将自己注册到Nacos服务器上,服务消费者通过Nacos服务器获取可用的服务实例列表,并通过心跳检测和负载均衡来实现服务的动态发现和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值