栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Nacos服务注册与发现中心之服务提供者心跳机制(服务端代码)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Nacos服务注册与发现中心之服务提供者心跳机制(服务端代码)

上篇说了Nacos服务注册与发现中心的服务注册在服务端的代码,接下来看服务提供者与Nacos服务器之间心跳机制的服务端的代码

文章目录
  • 入口URI
  • 一、InstanceController
    • service.processClientBeat(clientBeat);
  • END


入口URI

在介绍服务注册者注册服务的客户端代码的文章中,有讲过:服务提供者在注册服务的同时会启动一个定时任务,每5秒会发送一次心跳请求到Nacos服务端。通过客户端的源码我们可以得出,该URI为:/nacos/v1/ns/instance/beat, 请求方法为PUT。

一、InstanceController

此URI的处理类,依旧的InstanceController,我们先来看Controller层的源码:

 @CanDistro
    @RequestMapping(value = "/beat", method = RequestMethod.PUT)
    public JSONObject beat(HttpServletRequest request) throws Exception {
		
		// ... 省略不关心的代码
		
		// 1
        Instance instance = serviceManager.getInstance(namespaceId, serviceName, clientBeat.getCluster(), clientBeat.getIp(),
            clientBeat.getPort());

        if (instance == null) {
            instance = new Instance();
            instance.setPort(clientBeat.getPort());
            instance.setIp(clientBeat.getIp());
            instance.setWeight(clientBeat.getWeight());
            instance.setMetadata(clientBeat.getMetadata());
            instance.setClusterName(clusterName);
            instance.setServiceName(serviceName);
            instance.setInstanceId(instance.generateInstanceId());
            instance.setEphemeral(clientBeat.isEphemeral());

            serviceManager.registerInstance(namespaceId, serviceName, instance);
        }
		
        Service service = serviceManager.getService(namespaceId, serviceName);

        if (service == null) {
            throw new NacosException(NacosException.SERVER_ERROR, "service not found: " + serviceName + "@" + namespaceId);
        }
		
		// 2
        service.processClientBeat(clientBeat);

        return result;
    }

我们将代码关键处标上1,2标注。
我们先看1处的代码:通过NameSpaceId,serviceName,实例的ip和端口号,尝试获取实例在服务端的信息,如果获取不到,会先进行一次服务的注册,至于服务注册的代码,我们在上篇文章已经进行过讲解了。
在标注2处,会进行真正的心跳处理。

service.processClientBeat(clientBeat);

我们再来看service.processClientBeat(clientBeat);的代码

    public void processClientBeat(final RsInfo rsInfo) {
        ClientBeatProcessor clientBeatProcessor = new ClientBeatProcessor();
        clientBeatProcessor.setService(this);
        clientBeatProcessor.setRsInfo(rsInfo);
        HealthCheckReactor.scheduleNow(clientBeatProcessor);
    }

可以看到,这里创建了一个异步任务ClientBeatProcessor,我们再来看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 instances = cluster.allIPs(true);

        for (Instance instance : instances) {
            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.getNamespaceId(), this.service.getName());
                    }
                }
            }
        }
    }

此处可以看到,任务的主要逻辑是先获取到对应的实例列表,再遍历去获取ip和端口号相同的实例,然后更新实例的最后一次心跳时间和更新实例的健康状态,最后会进行一次服务状态变更的通过:这里是通过UDP的方式通知服务消费者,具体逻辑会在介绍服务消费者时再细说。

END

可以看到服务端心跳的代码还是相对简单清晰的,下一篇将会开始介绍服务消费者相关的逻辑以及源码。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1005700.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号