Nacos 注册中心是什么?如何使用?

Nacos 的配置中心的使用我们已经了解👉使用 SpringBoot 连接 Nacos 配置中心实现配置的热更新 - 掘金 (juejin.cn) ,本篇介绍如何使用 Nacos 的注册中心。

一、Nacos 注册中心

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

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

(一)生产者实现

这里假设你已经知道如何创建多模块项目。(如何创建?👉构建强大的 Spring Boot 多模块项目:一步步指南 - 掘金 (juejin.cn)

  1. 将服务注册到 Nacos

创建一个 SpringBoot 多模块项目,在父模块的pom文件中添加以下依赖:

xml 复制代码
<!--   Spring MVC     -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


<!--    注册中心依赖    -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. 创建两个子模块,分别在配置文件中(application.yml)设置 Nacos 服务端信息
yml 复制代码
#配置 nacos 注册中心
spring:
  application:
    name: nacosRegisterDemo1 #服务名称
  cloud:
    nacos:
      discovery:
      	# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Naco 服务器主机和端口
        server-addr: localhost:8848
        username: nacos
        password: nacos

#动态端口号,子模块的端口号
server:
  port: 0

分别在子模块中创建一个测试接口

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/getname")
    public String getNameById(Integer id){
        return "lishi-"+id;
    }
}
  1. 启动 Nacos 服务、运行两个子模块,打开 Nacos 控制台http://localhost:8848/nacos/index.html。

点击"详情":

可以看到每个子模块的ip+端口信息,可以根据ip、端口来访问接口(这不是重点)。

(二)消费者实现

注册中心消费者的实现要复杂一些,消费者要调用生产者的HTTP接口,需要引入SpringCloudOpenFeign进行HTTP调用(构造HTTP请求来调用生产者的接口);为了实现负载均衡,还要添加客户端负载均衡器SpringCloudLoadBalancer。这里的消费者,就是一个模块调用其它模块的服务(接口),就好比用浏览器来调用后端接口一样。这样做是来看看模块间是如何通信的。

  1. 添加如下依赖到父模块的pom.xml
xml 复制代码
<!--    负载均衡器    -->
<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>
  1. 创建一个子模块consumer当作消费者
  1. 配置 Nacos 服务信息(在consumer中的pom.xml
yml 复制代码
spring:
  application:
    name: nacosRegisterDemo1
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        register-enabled: false #表示不需要注册到注册中心
server:
  port: 8080 #消费者需要一个固定端口
  1. 在启动类上添加@EnableFeignClients注解,用来开启OpenFeign
java 复制代码
@SpringBootApplication
@EnableFeignClients    //开启 OpenFeign
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
  1. 编写 OpenFeign调用代码,创建一个UserService用来测试
java 复制代码
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Service
@FeignClient("nacosRegisterDemo1") //表示调用 nacos 中的 nacosRegisterDemo1 服务
public interface UserService {
    /**
     * 调用"nacosRegisterDemo1服务中生产者的 /user/getname 接口,该接口为:根据id 获取姓名"
     * @param id
     * @return
     */
    @RequestMapping("/user/getname")
    String getNameById(@RequestParam("id") Integer id);//@RequestParam 一定不能省略。在使用OpenFeign进行服务间通信时,需要使用@RequestParam注解来明确指定哪个方法参数应该绑定到哪个HTTP请求参数。
}

@FeignClient("")里的内容一定要跟 Nacos 中的服务名一致。

@RequestMapping("")中的url要跟待调用的生产者模块中的url相同,跟单体项目前端调用后端时的url一样。

  1. 调用Openfeign接口代码
java 复制代码
@RestController
public class BusinessController {

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

此时我有两个生产者(子模块)pro_1pro_2,它们的测试接口:

pro_1:

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getname")
    public String getNameById(Integer id){
        return "lishi-"+id+"-pro_1";
    }
}

pro_2:

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/getname")
    public String getNameById(Integer id){
        return "lishi-"+id+"-pro_2";
    }
}

现在在浏览器中输入http://localhost:8080/getnamebyid?id=1它就会调用 nacosRegisterDemo1 服务中生产者的"/user/getname"接口,但是pro_1pro_2url是一样的,那返回的到底是哪一个值呢?我们直接全部启动,然后访问http://localhost:8080/getnamebyid?id=3

好像访问的是pro_1难道真是这样吗?再刷新一次:

又访问了pro_2了。因为在使用OpenFeign进行服务间通信时,默认的负载均衡策略是轮询调用。这意味着,如果服务集群中有多个实例提供了同一个接口,OpenFeign会依次将请求分发到每个实例上,每个实例都有平等的机会被调用。这种方式可以确保所有的服务实例都能得到均匀的负载,避免了某些实例被过度使用而其他实例空闲的情况。

(OpenFeign以及LoadBalancer负载均衡等详细的内容后续会更新,本篇只是演示注册中心的使用方法以及作用)

(三)注册中心的交互流程

看完上面一巴拉的文字可能还是有一点蒙,不过没关系,下面用图来描述整个过程。

上面的pro_1pro_2就相当于服务提供者,它们都注册到了Nacos的注册中心。接着consumer(消费者)也把自己注册到注册中心,这时它可以拉取服务列表,看到有哪些服务提供者,从而调用该服务(通过OpenFeign来调用)。

(四)注册中心参数说明

  1. 分组 :注册服务所在的组名,默认为 DEFAULT_GROUP,可以在配置文件中spring.cloud.nacos.discovery.group=groupName来设置。

  2. 保护阈值:健康节点要求的最小百分比。保护阈值应设置为一个0到1之间的小数,当集群中的健康实例占比小于保护阈值时,会触发保护功能。触发后,Nacos 在触发保护功能后,会根据实例的健康状态和权重,计算出一个有效权重,然后按照有效权重的比例返回实例给调用者。这样,健康的实例会有更高的概率被选中,而非健康的实例会有更低的概率被选中,阻止流量过度向少量实例集中。

  3. 临时实例/永久实例 :Nacos 中的实例分为临时实例和永久实例,临时实例的生命周期和服务的运行周期相同,服务停止运行 Nacos 中就会将临时实例删除;而永久实例即使程序终止,也会保留到 Nacos 中。可以在配置文件中使用spring.cloud.nacos.discovery.ephemeral=false设置为永久实例。

  4. 权重:用于实现负载均衡,取值范围 0 到 10000,数值越大权重越大,被分配到的概率越大。取值为 0 时表示下线。

相关推荐
小筱在线12 分钟前
在SpringCloud中实现服务间链路追踪
后端·spring·spring cloud
黄俊懿3 小时前
【深入理解SpringCloud微服务】了解微服务的熔断、限流、降级,手写实现一个微服务熔断限流器
java·分布式·后端·spring cloud·微服务·架构·手写源码
Xua30553 小时前
浅谈Spring Cloud:OpenFeign
后端·spring·spring cloud
c1tenj25 小时前
SpringCloud Feign 以及 一个标准的微服务的制作
java·spring cloud·微服务
爱笑的源码基地6 小时前
Java+Spring Cloud +UniApp 智慧工地源码,用户PC端、移动端数据同步,支持多端展示
人工智能·spring cloud·源码·软件开发·智慧工地·智慧工地app·住建数据监管
装不满的克莱因瓶12 小时前
【微服务】Eureka的自我保护机制
java·spring cloud·云原生·eureka·注册中心·服务注册
記億揺晃着的那天15 小时前
SpringCloud从零开始简单搭建 - JDK17
java·spring boot·后端·spring cloud·nacos
aloha_7891 天前
B站宋红康JAVA基础视频教程(chapter14数据结构与集合源码)
java·数据结构·spring boot·算法·spring cloud·mybatis
你知道“铁甲小宝”吗丶2 天前
【第33章】Spring Cloud之SkyWalking服务链路追踪
java·spring boot·spring·spring cloud·skywalking
ღ᭄ꦿ࿐Never say never꧂2 天前
微服务架构中的负载均衡与服务注册中心(Nacos)
java·spring boot·后端·spring cloud·微服务·架构·负载均衡