服务注册与发现:Nacos

为什么需要服务注册与发现

假设 mafeng-user 用户微服务部署了多个实例(组成集群模式),如下图所示:

会出现以下几个问题:

  • mafeng-order订单微服务发出Http远程调用时,该如何得知mafeng-user实例的IP和端口呢?
  • 在多个mafeng-user实例的情况下,mafeng-order该选择哪个实例进行调用呢?
  • mafeng-order如何得知mafeng-user实例状态是否健康?
微服务架构出现的以上问题, Spring Cloud 框架引入了 服务注册与发现 组件把这些问题很好地解决了!
Spring Cloud 框架里面,我们不止只有一种 服务注册与发现 组件,而是有四种比较常用的组件:
  • Eureka
  • Zookeeper
  • Consul
  • Nacos

Nacos简介

Nacos Alibaba 开发的是用于微服务管理的平台,其核心功能是服务注册与发现、集中配置管理。有了之前的一系列相关的技术的学习,Nacos 学习和使用起来就简单多了。
  • Nacos作为 服务注册发现 组件,可以替换Spring Cloud应用中传统的服务注册于发现组件,如:
  • EurekaZookeeperConsul等,支持服务的健康检查。
  • Nacos作为服务配置中心,可以替换ApolloSpring Cloud ConfigBus
官网: https://nacos.io/
当然, Nacos 作为一个微服务管理平台,除了面向 Spring Cloud ,还支持很多其他的微服务基础设施,
如: Docker Dubbo kubernetes 等。除了核心的服务注册与发现和配置管理功能,还提供了各种服
务管理的功能特性,如:动态 DNS 、服务元数据管理等。
所以当你的微服务架构为了维护众多的独立部署的基础组件而烦恼的时候, Nacos 可以在一定程度上解决你的烦恼。

搭建Nacos单机

WIndow方式启动

下载 nacos 压缩包
  • nacos-server-2.1.1.zip
解压进入 bin 目录执行
  • startup.cmd -m standalone
如下图效果,代表启动完成
浏览器访问
http://localhost:8848/nacos

账户密码默认为nacos

Docker方式启动

拉取nacos最新镜像

docker pull nacos/nacos-server:2.0.3

创建容器

docker run --env MODE=standalone --restart=always --name nacos -d -p 8848:8848 - p 9848:9848 -p 9849:9849 nacos/nacos-server:2.0.3

注意: Nacos2.0版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口:98489849 Nacos官网 | Nacos 官方社区 | Nacos 下载 | Nacos

端口

与主端口的偏移

描述

9848

1000

客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求

9849

1001

服务端gRPC请求服务端端口,用于服务间同步等

访问:http://192.168.66.133:8848/nacos,同window

服务注册到Nacos单机

mafeng-usermafeng-order都需要注册到Nacos,步骤相同

导入nacos依赖

因为Nacos 属于 SpringCloudAlibaba 体系的组件,所以要单独锁定 spring - cloud - alibaba-

dependencies

在父工程锁定依赖版本:

<properties>
<springcloud.alibaba.version>2.2.9.RELEASE</springcloud.alibaba.version>
</properties>


<!-- nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${springcloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

以上配置加到dependencyManagement 里面

PS:关于SpringCloudAlibaba的与SpringCloud的版本关系说明:

https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E 6%98%8E

在子工程再导入nacos依赖:

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

配置yml连接nacos

spring: 
    cloud:
        nacos:
            discovery:
                server-addr: 192.168.66.133:8848

注意:这里虽然8848端口,但会自动偏移+1000,真正连接的是gRPC端口:9848

重启服务,查看Nacos客户端

临时实例和持久实例

在服务注册时有一个属性ephemeral 用于描述当前实例在注册时是否以临时实例出现;

  • true则为临时实例(默认值);
  •  false则为持久实例;

临时实例

  • 默认情况,服务实例仅会注册在Nacos内存,不会持久化到Nacos磁盘,其健康检测机制为Client 模式,即Client主动向Server上报其健康状态(类似于推模式);
  • 默认心跳间隔为5秒,在15秒内Server未收到Client心跳,则会将其标记为不健康状态;在30秒内若收到了Client心跳,则重新恢复健康状态,否则该实例将从Server端内存清除。即对于不健康的实例,Server会自动清除;
  • Nacos的临时实例 选择采用AP模式 ,采用distro协议实现

持久实例

  • 服务实例不仅会注册到Nacos内存,同时也会被持久化到Nacos磁盘,其健康检测机制为Server 模式,即Server会主动去检测Client的健康状态(类似于拉模式);
  • 默认每20秒检测一次,健康检测失败后服务实例会被标记为不健康状态,但不会被清除,因为其是持久化在磁盘的,其对不健康持久实例的清除,需要专门进行;
  • Nacos的持久实例 选择采用CP模式 ,采用raft协议实现

应用场景

  • 临时实例:适合于存在突发流量暴增可能的互联网项目,可以实现弹性扩容,正常生产中的环境就 是这样;
  • 持久实例:用于保护阈值,比如说服务A100个实例,那么当有98个不可用时:
    • 如果是临时实例,则只会返回两个服务,那么大并发量请求这两个服务肯定会造成雪崩的, 造成整个服务不可用;
  • 如果是持久实例,实例会全部返回,虽然有98个不可用,消费者可能会请求失败,但不至于剩下的两个健康实例崩溃;

Nacos环境隔离

Nacos既是注册中心,又是数据中心。为了便于管理,Nacos提供了namespace来实现环境隔离功能。用于进行租户级别的隔离,我们最常用的就是不同环境比如测试环境,线上环境进行隔离。

  • nacos中可以有多个namespace
  • namespace下可以有group等。业务相关性比较强的可以放在一组,比如:支付和订单不同namespace之间相互隔离,即不同namespace的服务互相不可见

创建新的namespace

服务配置namespace

修改mafeng-usernamespace,加入devnamespace

spring: 
    cloud:
        nacos:
            discovery:
                server-addr: 192.168.66.133:8848 
                ephemeral: true
                namespace: fb99a686-aa07-4ed4-a574-684e1f889189

Nacos数据持久化

默认存储

默认采用内嵌式数据库 Derby 数据库,数据存放在 /nacos/data/derby-data 目录下:

Nacosnamespacegroup、持久实例信息等都会持久化写入Derby数据库。

切换为MySQL

做小型工程,用Derby数据库还行,但中大型应用更建议使用MySQL。我们尝试切换为MySQL

1、登录nacos容器:

docker exec -it nacos /bin/bash

2、修改conf/application.properties文件,在最后追加以下内容

SPRING_DATASOURCE_PLATFORM=mysql 
MYSQL_DATABASE_NUM=1 
MYSQL_SERVICE_HOST=192.168.66.133 
MYSQL_SERVICE_PORT=3306 
MYSQL_SERVICE_DB_NAME=nacos 
MYSQL_SERVICE_USER=root 
MYSQL_SERVICE_PASSWORD=root
 

3、在mysql导入nacos-mysql.sql 

4、重启nacos

docker restart nacos

搭建Nacos集群

Nacos集群架构

搭建集群

我们采用docker-compose搭建,过程轻松简单。

1、上传nacos-docker-master/root目录下

2、查看example/docker-compose.yml文件内容

version: "3.3"
services:
  nacos1:
    hostname: nacos1
    container_name: nacos1
    image: nacos/nacos-server:2.0.3
    volumes:
      - ./cluster-logs/nacos1:/home/nacos/logs
    ports:
      - "8861:8848"
      - "9861:9848"
      - "10555:9555"
    env_file:
      - ../env/nacos-hostname.env
    restart: always
    depends_on:
      - mysql

  nacos2:
    hostname: nacos2
    image: nacos/nacos-server:2.0.3
    container_name: nacos2
    volumes:
      - ./cluster-logs/nacos2:/home/nacos/logs
    ports:
      - "8862:8848"
      - "9862:9848"
    env_file:
      - ../env/nacos-hostname.env
    restart: always
    depends_on:
      - mysql

  nacos3:
    hostname: nacos3
    image: nacos/nacos-server:2.0.3
    container_name: nacos3
    volumes:
      - ./cluster-logs/nacos3:/home/nacos/logs
    ports:
      - "8863:8848"
      - "9863:9848"
    env_file:
      - ../env/nacos-hostname.env
    restart: always
    depends_on:
      - mysql

  mysql:
    container_name: mysql8
    image: nacos/nacos-mysql:8.0.16
    env_file:
      - ../env/mysql.env
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3307:3306"


  nginx:
    image: nginx:latest
    restart: always
    ports:
      - "8801:80"
    volumes:
      - ../nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ../nginx/conf/conf.d:/etc/nginx/conf.d
      - ../nginx/log:/var/log/nginx
      - ../nginx/html:/usr/share/nginx/html
    container_name: "nginx"
    depends_on:
      - nacos1
      - nacos2
      - nacos3

3、查看nginx/conf/nginx.conf文件内容:

user  nginx;
worker_processes  auto;
 
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
 
 
events {
    worker_connections  1024;
}
 
stream
{
    upstream nacos {
        server 192.168.66.133:9861;
        server 192.168.66.133:9862;
        server 192.168.66.133:9863;
    }
 
 
    server {
        listen  80;
        proxy_pass nacos;
    }
}

4、在example根目录下执行

docker-compose up -d

等待所有容器启动

5、访问集群

http://192.168.66.133:8861/nacos

服务注册到Nacos集群

mafeng-usermafeng-orderNacos连接地址改为:

spring: 
    cloud:
        nacos:
            discovery:
                server-addr: 192.168.66.133:7801 # 7801(程序端口)+1000(偏移量)=8801(Nginx端口)

各大注册中心产品的相同点

作为服务注册中心,核心的服务注册功能和发现功能都是一样的。

项目中我们可以统一使用Spring Cloud框架的DiscoveryClient 对象实现服务发现和远程调用, 具体使用哪个注册中心产品是透明的。

各大注册中心产品的核心区别

核心对比

Nacos(推荐使用)

Eureka

Consul

Zookeeper

一致性协议

CPAP

AP

CP

CP

版本迭代

迭代升级中

不再升级

迭代升级中

迭代升级中

SpringCloud集成

支持

支持

支持

支持

Dubbo集成

支持

不支持

不支持

支持

K8S集成

支持

不支持

支持

不支持

Eureka优先支持AP

Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和 查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节

点,只要有一台Eureka还在,就能保证注册服务可用(保证强可用性AP),只不过查到的信息可能不是最 新的(不保证强一致性CP)

Zookeeper优先支持CP

Zookeeper在选举leader时,会停止服务,直到选举成功之后才会再次对外提供服务,这个时候就说明 了服务不可用,但是在选举成功之后,因为一主多从的结构,zookeeper在这时还是一个高可用注册中 心,只是在优先保证一致性的前提下,zookeeper才会顾及到可用性

Consul优先支持CP

1、服务注册相比Eureka会稍慢一些。因为Consulraft协议要求必须过半数的节点都写入成功才认 为注册成功

2Leader挂掉时,重新选举期间整个consul不可用。保证了强一致性但牺牲了可用性。

Nacos同时支持APCP(推荐使用)

Nacos的临时实例 选择采用AP模式 ,采用distro协议实现

Nacos的持久实例 选择采用CP模式 ,采用raft协议实现

相关推荐

  1. Nacos如何支持服务发现注册

    2024-03-15 15:50:01       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-15 15:50:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-15 15:50:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-15 15:50:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-15 15:50:01       20 阅读

热门阅读

  1. 《Effective Modern C++》- 极精简版 36-42条

    2024-03-15 15:50:01       19 阅读
  2. 记录启动Dubbo-admin遇到的问题

    2024-03-15 15:50:01       26 阅读
  3. 软考高级:软件工程集成测试的策略概念和例题

    2024-03-15 15:50:01       19 阅读
  4. Uniapp Vue2 image src动态绑定static目录下的图片

    2024-03-15 15:50:01       18 阅读
  5. 力扣题库第9题:找到字符串中所有的异位词

    2024-03-15 15:50:01       21 阅读
  6. Web安全攻防措施

    2024-03-15 15:50:01       20 阅读
  7. 程序分享--排序算法--冒泡排序

    2024-03-15 15:50:01       20 阅读
  8. int8量化和int16量化的区别

    2024-03-15 15:50:01       17 阅读
  9. 力扣题库第10题:和为K的子数组

    2024-03-15 15:50:01       17 阅读
  10. 在Odoo中定义基于SQL视图的模型

    2024-03-15 15:50:01       22 阅读