• Nacos手摸手教学【二】Nacos注册中心


    前言

    上一篇我们说到Nacos作为动态配置中心,那么这篇来聊聊Nacos作为服务注册中心。注册中心其实就类似于企查查这种平台,把公司信息汇合到这个平台方便别人使用。我们把服务注册到Nacos也就是为了让别人发现我们的服务并且使用它。

    本文基于Cloud Alibaba 2021.0.1.0 + Springboot 2.6.3

    搭建服务

    首先还是以单机模式启动nacos-serve

    startup.cmd -m standalone

    服务提供者与服务消费者的pom中均添加以下场景启动器

    1. com.alibaba.cloud
    2. spring-cloud-starter-alibaba-nacos-config
    3. 2021.0.1.0
    4. com.alibaba.cloud
    5. spring-cloud-starter-alibaba-nacos-discovery
    6. 2021.0.1.0
    7. org.springframework.cloud
    8. spring-cloud-starter-bootstrap
    9. 3.1.2

    我这里基于【Nacos手摸手教学一】来做的,服务提供者的bootstrap.yml 注意修改namespace、ip

    1. spring:
    2. cloud:
    3. nacos:
    4. config:
    5. server-addr: ip:8848
    6. file-extension: yaml
    7. namespace: 434e7801-0b5d-4fd2-b96a-acbac849fd84
    8. discovery:
    9. server-addr: ip:8848
    10. application:
    11. name: provider-serve
    12. profiles:
    13. active: dev

    服务消费者的配置文件一样的,不一样的也就是服务名consumer-serve

    接下来我们启动两个服务,回到nacos控制台

    原理

    服务确实注册到Nacos了,表面来看我们相当于登记了姓名,那么如果我把某个服务停了,nacos又是如何知道该服务还能不能正常使用的呢?我们不仅要知其然,也要知其所以然。

    大致流程:每个服务都会有一个nacos client,它用来和nacos server打交道,用来具体的服务注册、查询等操作,服务提供者在启动的时候会向nacos server注册自己,服务消费者在启动的时候订阅nacos server上的服务提供者。

    NacosNamingService 中的 registerInstance 方法用于向Nacos注册实例,Nacos 中的实例分为临时和永久2种类型,注册前先判断实例是否是临时实例(默认都是临时实例),如果是Instance是临时实例,则创建一个 BeatTask 心跳线程定期调用 HTTP PUT /instance/beat 向 Nacos 服务器发送心跳,然后调用 HTTP POST /instance 向 Nacos 服务器注册实例。

    BeatTask 线程通过 HTTP PUT /instance/beat 向 Nacos 发送心跳请求,如果当前实例在服务器上不存在,则重新注册实例,否则等待执行下一次心跳。以下源码来自BeatReactor类

    1. @Override
    2. public void run() {
    3. if (beatInfo.isStopped()) {
    4. return;
    5. }
    6. //下一次心跳时间
    7. long nextTime = beatInfo.getPeriod();
    8. try {
    9. //发送心跳
    10. JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
    11. long interval = result.get("clientBeatInterval").asLong();
    12. boolean lightBeatEnabled = false;
    13. if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
    14. lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
    15. }
    16. BeatReactor.this.lightBeatEnabled = lightBeatEnabled;
    17. //使用服务器返回的心跳时间
    18. if (interval > 0) {
    19. nextTime = interval;
    20. }
    21. int code = NamingResponseCode.OK;
    22. if (result.has(CommonParams.CODE)) {
    23. code = result.get(CommonParams.CODE).asInt();
    24. }
    25. //服务器返回实例不存在,重新注册实例
    26. if (code == NamingResponseCode.RESOURCE_NOT_FOUND) {
    27. Instance instance = new Instance();
    28. instance.setPort(beatInfo.getPort());
    29. instance.setIp(beatInfo.getIp());
    30. instance.setWeight(beatInfo.getWeight());
    31. instance.setMetadata(beatInfo.getMetadata());
    32. instance.setClusterName(beatInfo.getCluster());
    33. instance.setServiceName(beatInfo.getServiceName());
    34. instance.setInstanceId(instance.getInstanceId());
    35. instance.setEphemeral(true);
    36. try {
    37. //重新注册实例
    38. serverProxy.registerService(beatInfo.getServiceName(),
    39. NamingUtils.getGroupName(beatInfo.getServiceName()), instance);
    40. } catch (Exception ignore) {
    41. }
    42. }
    43. } catch (NacosException ex) {
    44. NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
    45. JacksonUtils.toJson(beatInfo), ex.getErrCode(), ex.getErrMsg());
    46. }
    47. //开启下一次心跳
    48. executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
    49. }

    服务端也会为每个 Service 启动一个 ClientBeatCheckTask 线程用于检测该 Service 下所有的实例的健康状态,如果实例的 lastBeat 最后心跳时间超过了心跳超时时间(默认15秒),则设置 healthy 健康状态为 false,并通过 UDP 向客户端 push 最新的数据,如果 lastBeat 超过30秒,表示此实例已不可用,通过调用 HTTP DELETE /instance 从实例列表中删除该实例。

  • 相关阅读:
    MindSpore优秀论文5:[AAAI] CycleCol:基于循环卷积神经网络对真实单色-彩色摄像系统着色
    如何画产品架构图?
    非稳压高压电源模块12SMV300 HV05200S-W2 HV12180S-2W直流转换器
    用Qt实现一个计算器demo
    GeoServer(配合Tomcat)安装与配置
    jmeter分布式压测
    初级 - 若依框架 - Java Spring/Spring Boot 项目理解记录
    网络安全(黑客)小白自学
    C++入门 第一篇(C++关键字, 命名空间,C++输入&输出)
    Python在工业自动化领域的应用详解
  • 原文地址:https://blog.csdn.net/QingXu1234/article/details/125945778