微服务系列:Spring Cloud Alibaba 之 Nacos 注册中心

720 阅读5分钟

继上一篇 微服务系列:服务网关 Spring Cloud Gateway 集成 Sentinel 限流 - 掘金 (juejin.cn) 完成 Spring Cloud Gateway 的基本学习之后,从这篇开始,我们进入 Nacos 的学习中。

Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。就是 注册中心 + 配置中心 的组合。

等价于:

Nacos = Eureka + Config + Bus

今天我们学习的是 Nacos 的作为注册中心的功能

话不多说,开始今天的学习。

基本介绍

  • 什么是注册中心

注册中心在微服务项目中扮演着非常重要的角色,是微服务架构中的纽带,类似于通讯录,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。

  • 为什么要使用注册中心

注册中心解决了服务发现的问题。在没有注册中心时候,服务间调用需要知道被调方的地址或者代理地址。当服务更换部署地址,就不得不修改调用当中指定的地址或者修改代理配置。而有了注册中心之后,每个服务在调用别人的时候只需要知道服务名称就好,继续地址都会通过注册中心同步过来。

  • Nacos 注册中心

Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

nacos

Nacos 具有如下特性:

  1. 服务发现和服务健康监测:支持基于DNS和基于RPC的服务发现,支持对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求;
  2. 动态配置服务:动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置;
  3. 动态 DNS 服务:动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务;
  4. 服务及其元数据管理:支持从微服务平台建设的视角管理数据中心的所有服务及元数据。

官方文档:nacos.io/zh-cn/docs/…

下载启动

这里我们选择在自己电脑的 Windows 系统下来启动 Nacos.

1. 安装包下载

可以从https://github.com/alibaba/nacos/releases下载nacos-server-$version.zip包。

image.png

除了安装包下载还有源码下载,详见官方文档。

2. 命令启动

Windows 下载解压后(.zip), 启动命令如下(standalone 代表着单机模式运行,非集群模式):

startup.cmd -m standalone

Nacos 默认是集群模式cluster,可以设置startup.cmd属性MODE单机模式standalone

set MODE="standalone"

image.png

3. 打开控制台

上一步启动成功之后,我们就可以访问 http://localhost:8848/nacos/index.html 进入可视化控制台页面。 默认的用户名和密码都是nacos

image.png

如何使用

1. 添加依赖

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

<!-- SpringBoot Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。

更多版本对应关系参考:版本说明 Wiki

2. 添加 Nacos 配置

server:
  port: 9201

# Spring
spring:
  application:
    # 应用名称
    name: cloud-nacos-provider
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848

3. @EnableDiscoveryClient 开启服务注册发现功能

@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {

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

    @RestController
    class EchoController {
        @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
        public String echo(@PathVariable String string) {
            return "Hello Nacos Discovery " + string;
        }
    }
}

@EnableDiscoveryClientSpring Cloud 的原生注解,在高版本中可以不用添加这个注解,默认自动开启服务注册。

观察到这里还有一个测试接口,浏览器访问 http://localhost:9201/echo/ezhang 试试:

image.png

4. 启动服务,观察 Nacos 控制台服务列表

image.png

我们的服务提供者就成功注册进去了。

测试验证

在上一步我们已经将 服务提供者 配置好了。接下来,我们配置一个服务消费者,并使服务消费者可以通过 Nacos 的服务注册发现功能从 Nacos server 上获取到它要调用的服务。

新建一个项目 cloud-nacos-consumer,配置步骤和 服务提供者 的步骤一样。

1. application.yml 文件

server:
  port: 9202

# Spring
spring:
  application:
    # 应用名称
    name: cloud-nacos-consumer
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848

2. NacosConsumerApplication.java 文件

@SpringBootApplication
public class NacosConsumerApplication {

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

    // 新增restTemplate对象注入方法,注意,此处 @LoadBalanced 注解一定要加上,否则无法远程调用
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @RestController
    public class TestController {

        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

        @RequestMapping(value = "/test/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
            return restTemplate.getForObject("http://cloud-nacos-provider/echo/" + str, String.class);
        }
    }

}

给 RestTemplate 实例添加 @LoadBalanced 注解,开启 @LoadBalanced 与 Ribbon 的集成:

3. 启动项目

观察 Nacos 控制台服务列表,发现已成功注册上去

image.png

4. 访问地址 http://localhost:9202/test/ezhang

image.png

测试通过。

负载均衡

1. 为什么 Nacos 支持负载均衡?

image.png

观察 nacos-discovery 包,发现里面集成了 ribbon

2. 测试验证 Nacos 的负载均衡。

(1)首先,将上面的 cloud-nacos-provider 子 module 复制出来一个 cloud-nacos-provider-copy,改一下端口号为 9211

server:
  port: 9211

# Spring
spring:
  application:
    # 应用名称
    name: cloud-nacos-provider
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848

(2)改一下 NacosProviderCopyApplicationNacosProviderApplication

@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderCopyApplication {

    @Value("${server.port}")
    private String serverProt;

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

    @RestController
    class EchoController {
        @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
        public String echo(@PathVariable String string) {
            return "Hello Nacos Discovery " + serverProt + string;
        }
    }
}

(3)启动项目,观察控制台

image.png

可以看到有两个服务提供者和一个服务消费者,点击服务提供者详情,看到两个实例没有问题。

image.png

(4)服务消费者代码保持不变,浏览器访问 http://localhost:9202/test/ezhang

QQ录屏20220105222709.gif

轮询 OK

主流服务注册中心对比

对比项目NacosEurekaConsulZookeeper
一致性协议支持AP和CP模型AP模型CP模型CP模型
健康检查TCP/HTTP/MYSQL/Client BeatClient BeatTCP/HTTP/gRPC/CmdKeep Alive
负载均衡策略权重/metadata/SelectorRibbonFabio-
雪崩保护
自动注销实例支持支持不支持支持
访问协议HTTP/DNSHTTPHTTP/DNSTCP
监听支持支持支持支持支持
多数据中心支持支持支持不支持
跨注册中心同步支持不支持支持不支持
SpringCloud集成支持支持支持不支持
Dubbo集成支持不支持不支持支持
k8s集成支持不支持支持不支持

从上面对比可以了解到,Nacos作为服务发现中心,具备更多的功能支持项,且从长远来看Nacos在以后的版本会 支持 SpringCLoud+Kubernetes 的组合,填补 2 者的鸿沟,在两套体系下可以采用同一套服务发现和配置管理的解 决方案,这将大大的简化使用和维护的成本。另外,Nacos 计划实现 Service Mesh,也是未来微服务发展的趋势。

Nacos 支持 AP 和 CP 模式的切换

C 是指所有节点在同一时间看到的数据是一致的;而 A 的定义是所有的请求都会收到响应

何时选择使用何种模式?

一般来说, 如果不需要存储服务级别的信息且服务实例是通过 nacos-client 注册,并能够保持心跳上报,那么就可以选择 AP 模式。当前主流的服务如 Spring Cloud 和 Dubbo 服务,都适用于 AP 模式, AP 模式为了服务的可用性而减弱了一致性,因此 AP 模式下只支持注册临时实例。

如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须的,K8S 服务和 DNS 服务则适用于 CP 模式。 CP 模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

补充

本文源码地址:gitee.com/zhang335654…

PS:都看到这里了,点个赞吧,彦祖!