Nacos-注册中心

一、注册中心的交互流程

注册中心通常有两个角色:

  •  服务提供者(生产者):对外提供服务的微服务应用。它会把自身的服务地址注册到注册中心,以供消费者发现和调用。
  • 服务调用者(消费者):调用其他微服务的应用程序。它会向注册中心订阅自己需要的服务,并基于服务提供者注册的信息发起远程调用

二、生产者实现

生产者实现步骤总共有以下3步:

  1. 添加 nacos-discovery 框架支持
  2. 配置 nacos 服务器端信息
  3. 编写调用接口

2.1 创建多模块项目

2.1.1 创建父模块

除了 pom.xml ,其他的全部删除

删除pom.xml 中多与依赖

标识当前父模块 

2.1.2 创建子模块

删除子模块 pom.xml

添加子模块 pom.xml

在父模块 pom.xml 中添加,规定打包顺序:

   <!--声明子模块-->
    <modules>
        <module>provider</module>
    </modules>

2.2 配置 nacos 服务器端信息

spring:
  application:
    name: nacos-discovery-demo #Nacos 服务名(命名不要使用下划线)
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        group: SIT_GROUP #设置分组
        ephemeral: false #设置此服务为永久实例
server:
  port: 0 #设置随机端口号

2.3 编写接口代码 

@RestController
@RequestMapping("/user")
public class UserController {

    //动态获取端口号
    @Autowired
    private ServletWebServerApplicationContext context;

    @RequestMapping("/getnamebyid")
    public String getUserByID(int id){
        return "provider-name:"+id+" | srever-port:"+context.getWebServer().getPort();
    }
}

三、实现消费者

3.1 添加框架支持

由于在父节点已经添加过相关依赖,在子节点可以不用添加

<dependency>
    <groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

3.2 配置Nacos

spring:
  application:
    name: nacos-consumer-demo
  cloud:
    nacos:
      discovery:
        username: nacous
        password: nacous
        server-addr: localhost:8848
        register-enabled: false #不注册到注册中心
        
server:
  port: 58080

3.3 开启 OpenFeign

@SpringBootApplication
@EnableFeignClients
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

}

3.4 声明 OpenFeign 式的 Service

@Service
@FeignClient("nacos-discovery-demo") //表示调用的 nacos 中的 nacos-discovery-demo 服务
public interface UserService {
    @RequestMapping("/user/getnamebyid")  //表示调用生产者服务: nacos-discovery-demo 中的 /user/getnamebyid 接口
    public String getNameById(@RequestParam("id") int id);
}

3.5 调用服务

@RestController
public class BusinessController {
    @Autowired
    private UserService userService;

    @RequestMapping("/getnamebyid")
    public String getNameById(@RequestParam("id") Integer id){
        return userService.getNameById(id);
    }

}

3.6 使用 RestTemplate 实现消费者

@SpringBootApplication
@EnableFeignClients
public class RestTemplateConsumerApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RestTemplateConsumerApplication.class, args);
    }

}

@RestController
public class BusinessController {
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/getnamebyid")
    public String getNameById(Integer id){
        return restTemplate.getForObject("http://nacos-discovery-demo/user/getnamebyid?id="+id,
                String.class);
    }
}

 

四、注册中心参数说明

  • 服务名:在yml中设置的名字
    spring:
      application:
        name: nacos-discovery-demo #Nacos 服务名(命名不要使用下划线)
  •  分组:注册服务所在的组名,默认时DEFAULT_GROUP,可以在配置文件中自定义
    spring:
      cloud:
        nacos:
          discovery:
            group: prod-test
  • 保护阈值:健康节点要求的最小百分比。用于在出现不健康实例时,阻止流量过度向少量健康实例集中,保护阈值应设置为一个0到1 之间的浮点数,默认值为0。当集群中的健康实例占比小于设置的保护阈值时,就会触发阈值保护功能。触发保护阈值后,Nacos 会将全部实例(健康实例+非健康实例)返回给调用者,虽然可能会损失一部分流量,但能保证集群中剩余的健康实例能正常工作。 
  • 服务路由类型:用于实现不同的路由需求,常见的路由类型有:
    none:默认路由,基于权重的轮询负载均衡路由策略
    label:标签路由,相同标签的实例会被聚合为一个集群,不同标签则实现流量隔离。
  • 临时实例:Nacos 中的实例分为临时实例和永久实例,临时实例的声明周期和服务的运行周期相同,服务停止运行,Nacos中就会将临时实例删除;而永久实例即使程序终止,也会保留在Nacos 中。在配置文件中通过:spring.cloud.nacos.discovery.ephemeral=false 来设置为永久实例。
  • 权重:用于实现负载均衡,取值范围 0 到 10000,数值越大,权重越大,负载均衡被分配的概率也就越高。设置为 0 的时候表示下线。

label 标签的实现:Nacos指南-服务发现:CMDB功能解析_nacos 服务路由类型-CSDN博客

权重的配置:Nacos- 负载均衡和服务实例的权重配置 - 明天,你好啊 - 博客园 (cnblogs.com)

临时实例和永久实例

  • 永久实例:是指注册到 Nacos 的服务实例,其注册信息会一直保留在 Nacos 服务器上,直到主动注销或被删除。这意味着即使服务实例下线或不可用,它的注册信息仍会保留在Nacos 上,直到显式取消注册。永久实例适用于需要长期存在的服务,比如稳定部署的服务或长时间运行的后端服务。
  • 临时实例: 是指注册到Nacos 的服务实例,其注册信息在实例下线或不可用时会自动被删除。如果服务实例下线、断开连接或主动注销,Nacos 会自动从注册表中删除这些实例的信息。临时实例适用于临时性的服务实例,比如临时加入集群的短期任务或特定场景下的临时服务。

临时实例健康检测机制 

  • 客户端主动上报机制:通过 OpenAPI 的注册方式,根据自身需求调用http接口对服务进行注册,然后通过Http 接口发送心跳到注册中心。在注册服务的同时会注册一个全局的客户端心跳检测任务。在服务一段时间没有收到来自客户端的心跳后,该任务会将其标记为不健康,如果在间隔的时间内还为收到心跳,那么该任务会将其剔除
  • 服务器端反向探测机制:通过SDK的注册方式,通过RPC与注册中心保持连接,客户端会定时的通过RPC连接向Nacos 注册中心发送心跳,保持连接的存活。如果客户端和注册中心的连接断开,那么注册中心会主动剔除该client 所注册的服务,达到下线效果。同时 Nacos 注册中心还会在注册中心启动时,注册一个过期客户端清除的定时任务,用于删除那些健康状态超过一段时间的客户端。 

五、Nacos 底层原理

5.1 配置自动刷新原理

Nacos 配置中心是支持配置项自动刷新的,而其实现的原理是通过 长轮询+事件驱动 的方式来实现的,具体来说:

  1. 客户端向 Nacos 服务器发送一个带有监听器(Listener)的请求,以获取某个特定配置的值。
  2. Nacos 服务器接收到请求后,会检查该配置是否发生了变化。如果没有变化,则该请求将被阻塞,直到超时或配置发生变化。
  3. 当配置发生变化时,Nacos 服务器会立即响应,并将新的配置值返回给客户端。
  4. 客户端接收到新的配置值后,可以根据需要更新自身的配置。

长轮询:服务器接收到客户端的请求之后,如果没有数据更新,则连接保持一段时间,直到有数据或者超时才会返回。 

Nacos2.x 后使用长连接

原因:

  1. 资源消耗:频繁的轮询对客户端和服务端都会造成不必要的开销
  2. 延迟感知:客户端获取到最新配置存在延迟,无法做到及时更新
  3. 扩展性限制:随着客户端数量的增长,服务端压力会显著增加

升级长连接优势:

  1. 建立长连接:客户端与服务端启动时即建立长连接,减少了请求时建立连接的开销
  2. 服务端推送:配置变更时,服务端直接通过长连接向客户端推送变更通知,而不是等待客户端下次轮询。
  3. 按需拉取:客户端接收到变更通知后,仅需拉取变更的配置列表,而不是全量拉取,进一步减少数据传输量和提升效率。
  4. 实时性增强:相比轮询,长连接下的配置更新几乎是实时的,极大地提高了配置变更的响应速度。

解释

  1. 通信效率大幅提升:减少了不必要的网络请求,减少了服务端压力,提升了整体系统的响应能力
  2. 降低延迟:客户端几乎能在配置更改的瞬间得到通知,减少了业务配置生效的时间差
  3. 资源优化:长连接避免了频繁的TCP链接建立与销毁,节约了系统资源,特别是对于大规模分布式系统而言

参考文档:https://nacos.io/en/blog/faq/nacos-user-question-history14710/

5.2 注册中心底层实现 

Nacos 注册中心的底层实现主要依赖于两个关键组件:服务注册(Service Register)和服务发现(Service Discovery)。

  • 服务注册:是指将服务实例的元数据(包括 IP 地址、端口号、服务名称等)注册到 Nacos 服务器上,以便其他服务能够发现和访问该服务。在服务启动时,它会向 Nacos 服务器发送一个注册请求,将自身的信息注册到特定的命名空间和分组中。
  • 服务发现:是指根据服务名称从 Nacos 服务器获取已注册的服务列表,并将其提供给需要调用该服务的服务消费者。消费者可以通过调用 Nacos 提供的 API 或集成 Nacos 客户端库来获取服务实例表。

具体来说,Nacos 注册中心的实现包括以下几个步骤:

  1. 服务注册:当服务启动时,它会向 Nacos 服务器发送一个注册请求,包含自己的元数据信息。Nacos 服务器接收到注册请求后,在内存中维护一个注册表,将服务实例的元数据保存起来,用于后续的服务发现。
  2. 心跳机制:注册成功后,服务实例会定期向Nacos 服务器发送心跳请求,以表明自己的健康状态和可用性。这样 Nacos 服务器可以监控各个服务实例的状态,并及时剔除不可用或下线的实例。
  3. 服务发现:当消费者需要访问某个服务时,它会向Nacos 服务器发送一个服务发现请求,包含所需服务的名称。Nacos 服务器根据服务名称查找注册表,并返回该服务的实例列表给消费者。
  4. 负载均衡:在服务发现的过程中,Nacos 还提供了负载均衡的支持。消费者可以选择合适的负载均衡策略来选择其中一个或多个服务实例进行调用。

5.3 Nacos 注册中心如何做到每秒百万级别的

底层通过使用 异步任务 + 内存队列 的方式来实现这一高并发任务的

当客户端组装好的服务实例发给服务器的时候,服务器接收到这个服务实例后,它并没有立即写入注册表,它是先放到内存队列中,而对于客户端来说,它收到的就是注册成功,我服务端这边就可以新起一个异步任务,慢慢将这些服务实例写入到注册表中。

大家都知道程序中,IO 操作是最耗时的,如果接收到服务实例后,立即写入注册表,那么就不可能实现百万级别的服务注册。

异步任务:异步处理注册请求,提高响应速度和吞吐量

内存对列 使用内存数据结构和内存队列优化读写速度和处理流程

  • 15
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值