在讨论Nacos之前,我们先讨论一下CAP理论

CAP理论是分布式场景绕不开的重要理论

一致性:所有节点在同一时间具有一样的数据;
可用性:保证每个请求不管成功还是失败都有响应;
分区容忍性:系统中任意信息的丢失和失败不会影响系统的继续运作;

关于分区容忍性P的理解,大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition),分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。

关于提高分区容忍性的办法,就是把同一份数据复制到多个节点上,分布到各个区里,容忍度就提高了。一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。

剩下CAP的C和A无法同时做到,原因是 如果C是第一需求的话,那么会影响A的性能,因为要数据同步,不然请求结果就会有差异,但数据同步会消耗时间,期间可用性就会降低。

如果A是第一需求的话,那么只要有一个服务在,就能正常接受请求,但是对于返回结果变化不能保证一致性,原因是在分布式部署的时候,不能保障每个环境下处理速度。

主流注册中心或配置中心产品一致性对比
Nacos Eureka Consul Zookeeper
CAP理论 CP+AP AP CP CP
Apache Zookeeper -> CP
与Eureka有所不同,Apache Zookeeper在设计时就遵循CP原则,即任何时候对Zookeeper访问请求能得到一致的数据结果,同时系统对网络分区具备容错性,但是Zookeeper不能保证每次服务请求都是可用的。

从Zookeeper的实际应用情况来看,在使用Zookeeper获取服务列表时,如果此时Zookeeper集群中的Leader节点宕了,该集群要进行Leader的重新选举,又或者Zookeeper集群中半数节点不可用,都将无法处理请求,所以说Zookeeper不能保证服务可用性。

在大部分分布式环境中,尤其是设计数据存储的场景,数据一致性是首先要保证的,这也是Zookeeper设计CP原则的另一个原因。

但是对于服务发现来说,情况就不太一样了,针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不同,也并不会造成灾难性后果。

因为对于服务消费者来说,能消费才是最重要的,消费者虽然拿到了可能不正确的服务提供者信息,也要胜过因无法获取实例而不去消费,导致系统异常要好。(消费者消费不正确的提供者信息可以进行补偿重试机制)

当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举,问题在于,选举Leader的时间太长,30~120s,而且选举期间整个zk集群是不可用的,这就导致整个选举期间注册服务瘫痪。

尤其在云部署环境下,因为网络问题使得ZK集群失去master节点是大概率事件,虽然服务能最终恢复,但是漫长的选举事件导致注册长期不可用是无法容忍的。

Spring Cloud Eureka -> AP

Spring Cloud Netflix 在设计 Eureka的时候遵循的是AP Eureka Server 也可以运行多个实例来构建集群,解决单点问题,但不同于Zookeeper选举leader的过程,Eureka Server采用的是Peer to Peer对等通信。这是一种去中性化的架构,无mater/salve之分,没一个Peer都是对等的。在这种架构风格中,节点通过彼此相互注册来提高可用性,每个节点需要添加一个或多个有效的serviceUrl指向其他节点。每个节点都可以视为其它节点的副本。

在集群环境中如果某台Eureka Server宕机,Eureka Client的请求会自动切换到新的Eureka Server节点上,当宕机的服务器重启恢复后,Eureka会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会在集群中进行复制(replicate to peer)操作,将请求复制到该Eureka Server当前所知的所有节点上。

当一个新的Eureka Server节点启动后,会首先尝试从相邻节点获取所有注册列表信息,并完成初始化。Eureka Server通过getEurekaServiceUrls()方法获取所有的节点,并且会通过心跳契约的方式定时更新。

默认情况下,主要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不能保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

Eureka不再从注册表中移除因为长时间没有收到心跳的服务;
Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(既保证当前节点可用);
当网络稳定时,当前实例新注册的信息会被同步到其它节点上;
因此,Eureka可以很好的应对网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使得整个注册中心瘫痪。

Alibaba Nacos -> AP/CP
Nacos是阿里开源的一个产品,主要针对微服务架构中的服务发现、配置管理、服务治理的综合性解决方案;

Nacos支持两种方式的注册中心,持久化和非持久化存储服务信息。

非持久化直接存储Nacos服务节点的内存中,并且服务节点采用去中心话的思想,服务节点采用Hash分片存储注册信息;
持久化使用Raft协议选举Master节点,同样采用半同步机制将数据存储在Leader节点上;
Nacos同时支持持久化和非持久化存储,也就是支持CAP原则中的AP和CP特性,Nacos的CP支持持久化和ZK模式类似。Nacos默认采用AP非持久化,非持久化使用内存存储性能更快,而且Hash分片存储,不利点就是某个服务挂点,可能出现部分部分时间点用失败。因为服务调用本身就是实时的,持久化存储起来意义不大,而且及时变化更合适。

HashiCorp Consul -> CP
Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。Consul使用Go编写,因此具有天然的移植性。

Consul内置了服务注册与发现框架、分布式一致性协议实现、健康检查、Key/Value存储、多数据中心方案。

Consul遵循CAP原理中的CP原则,保证了强一致性和分区容错性,且使用的是Raft算法,比Zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就下降了,例如服务注册的时间会稍微长一些,因为Consul的Raft协议要求必须过半数的节点都写入成功才算成功,在Leader挂掉了之后,重新选出Leader之前会导致Consul不可用。

Consul Template Consul 默认服务调用者需要依赖Consul SDK来发现服务,这就无法保证对应用的零入侵性。

通过Consul Template,可以定时从Consul集群获取最新的服务提供者列表并刷新Load Balance配置,这样对于服务调用者来说,只需要配置一个统一的服务调用地址即可。

Consul强一致性(C)带来的是:

服务注册相比Eureka会稍慢一些,因为Consul的Raft协议要求必须半数节点都写入成功才算注册成功;
Leader挂掉时,重新选举期间整个Consul不可用,保证了强一致性但是牺牲了可用性;
Eureka保证高可用(A)和最终一致性:

服务注册相对要快,因为不需要注册信息replicate到其他节点,也不保证注册信息是否replicate成功;
当数据存在不一致时,虽然A,B上注册的信息不相同,但是每个Eureka节点依然能够正常的对外提供服务,这会出现查询服务信息时如果A查不到,但请求B就能查的到,保证了可用性但牺牲了一致性;
另一方面,Eureka就是个Servlet程序,跑到Servlet容器中。Consul则是go编写而成。

什么是Nacos?

Nacos是阿里开源的一个产品,主要针对微服务架构中的服务发现、配置管理、服务治理的综合性解决方案;

Nacos的四大功能:

服务发现与服务健康检查;

动态配置管理;

动态DNS服务;

服务和源数据管理;

Zookeeper和Nacos的对比
Nacos在微服务场景中,主要用于配置中心和服务注册中心。这两块功能也是Zookeeper擅长的事情,以下我们分析下两者的不同处。

1.Zookeeper
Zookeeper的功能主要是它的树型节点来实现的。当数据变化的时候或者节点过期的时候,会通过事件触发通知对应的客户端数据变化了,然后客户端再请求ZK获取最新的数据,采用push-pull来做数据更新;

其中ZK最重要的就是它的ZAB协议了(消息广播和消息恢复)

消息广播:集群中ZK在数据更新的时候,通过Leader节点将消息广播给其他Follower节点,采用简单的两阶段提交模式,先Request->ACK->Commit,当超过一半的Follower节点响应时,就可以提交更新了;

奔溃恢复:当Leader挂了,或者超过半数Follower投票得出Leader不可用,那么会重新选举,这段时间内ZK服务是不可用的。通过最新的XID来选举出新的Leader,选举出来的后将新的Leader中的数据更新给超过半数的Follower节点后,此时才能对外提供服务;

2.Nacos
Nacos中配置中心和注册中心分别是两套实现,和ZK不同。

2.1 对比配置中心
Nacos和Zookeeper都可以作为配置中心,做一些可以实时变化的配置数据存储,然后实时更新线上数据。

Nacos:依赖Mysql数据库做数据存储,当数据更新的时候,直接更新数据库的数据,然后将数据更新的信息异步广播给Nacos集群中所有服务节点数据变更,再由Nacos服务节点更新本地缓存,然后将通知客户端节点数据变化。

Zookeeper:利用ZK的树型结构做数据存储,当有数据更新的时候,使用过半机制保证各个节点的数据一致性,然后通过ZK的事件机制通知客户端。

这里的差异:

服务器存储的位置不同,分别采用Mysql和ZK本身存储;

消息发送,一个采用过半机制保证一致性,另一个异步广播,通过后台线程重试保证;

2.2 对比注册中心
Nacos:支持两种方式的注册中心,持久化和非持久化存储服务信息。

非持久化 直接存储在Nacos服务节点的内存中,并且服务节点采用去中心话的思想,服务节点采用Hash分片存储注册信息;

持久化 使用Raft协议选举Master节点,同样采用过半机制将数据存储在Leader节点上;

Zookeeper:利用zk的树型结构做数据存储,服务注册和消费信息直接存储在zk树形节点上,集群下同样采用过半机制保证服务节点间一致性;

这里的差异:

Nacos同时支持 持久化和非持久化存储,也就是支持CAP原则中的AP和CP特性,Nacos的CP持久化和ZK模式类似。Nacos默认采用AP非持久化,非持久化使用内存存储速度更快,而且Hash分片存储,不利点就是某个服务挂掉,可能出现部分时间调用失败。因为服务调用本身就是实时的,持久化存储起来意义不大,反而及时变化更适合。
Nacos的基础概念

命名空间
命名空间(NameSpace)用于不同环境(开发环境、测试环境和生产环境)的配置隔离。不同的命名空间下,可以存在相同名称的配置分组(Group)或配置集。

配置分组
配置分组是对配置集进行分组,不同的配置分组下可以有相同的配置集(DateId)。默认的配置分组名称为 DEFAULT_GROUP。用于区分不同的项目或应用。

配置集
在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。

Nacos-Server部署
1.下载安装
//下载编译后的最新zip包
https://github.com/alibaba/nacos/releases

//解压
unzip nacos-server-$version.zip
cd nacos/bin

//启动
sh startup.sh -m standalone
2.测试注册中心和配置中心
//服务注册
curl -X POST ‘http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080’

//服务发现
curl -X GET ‘http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName’

//发布配置
curl -X POST “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld”

//获取配置
curl -X GET “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test”
3.登录Nacos-Server控制台

//访问
http://127.0.0.1:8848/nacos

//用户名&密码
nacos
nacos

Dubbo集成Nacos为注册中心 SpringCloud和Dubbo整合

Provider提供方:提供核心的Dubbo服务接口;

Consumer消费方:消费注册的Dubbo服务接口;

Nacos注册中心:配置、发现和管理Dubbo服务;

spring-cloud-dubbo-api 接口模块 提供接口层,供消费方,生产方复用

public interface DubboService {public String getInfo();
}

1.Nacos默认注册中心是AP实现,如果需要CP实现的业务可以进行如下设置;
curl -X PUT ‘http://127.0.0.1:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP’
2.修改Provider配置,将registry默认Zookeeper的地址改为Nacos地址

<?xml version="1.0" encoding="UTF-8"?>

核心依赖

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

服务端配置

配置文件

主要是Nacos注册中心和Dubbo两个核心配置。

server:port: 9010
spring:application:name: node10-dubbo-servercloud:nacos:discovery:server-addr: http://localhost:8848config:server-addr: http://localhost:8848file-extension: yaml
# Dubbo服务配置
dubbo:scan:base-packages: com.cloud.dubbo.serviceprotocol:name: dubboport: -1registry:address: spring-cloud://localhost

Dubbo 的配置:

dubbo.scan.base-packages : 指定 Dubbo 服务实现类的扫描基准包

dubbo.protocol : Dubbo 服务暴露的协议配置,其中子属性 name 为协议名称,port 为协议端口( -1 表示自增端口,从 20880 开始)

dubbo.registry : Dubbo 服务注册中心配置,其中子属性 address 的值 “spring-cloud://localhost”,说明挂载到 Spring Cloud 注册中心

早期 Dubbo Spring Cloud 实现必须配置 dubbo.registry.address = spring-cloud://localhost,后来版本将其配置变为可选 (参考 issue #592), 并且支持传统 Dubbo 协议的支持(参考 issue #588)

Spring Cloud 相关配置:

spring.application.name : Spring 应用名称,用于 Spring Cloud 服务注册和发现。

该值在 Dubbo Spring Cloud 加持下被视作 dubbo.application.name,因此,无需再显示地配置 dubbo.application.name

spring.main.allow-bean-definition-overriding : 在 Spring Boot 2.1 以及更高的版本增加该设定, 因为 Spring Boot 默认调整了 Bean 定义覆盖行为。(推荐一个好的 Dubbo 讨论 issue #3193)

spring.cloud.nacos.discovery : Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口

服务接口实现

import org.apache.dubbo.config.annotation.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@Service
public class DubboServiceImpl implements DubboService {private static final Logger LOGGER = LoggerFactory.getLogger(DubboServiceImpl.class) ;@Overridepublic String getInfo() {LOGGER.info("node10-dubbo-server start ...");return "node10-dubbo-server";}
}

注意:@Service是Dubbo框架中的注解,不是Spring框架的注解。

消费端配置

配置文件

server:port: 9011
spring:application:name: node10-dubbo-clientcloud:nacos:discovery:server-addr: http://localhost:8848config:server-addr: http://localhost:8848
# Dubbo服务配置
dubbo:protocol:name: dubboport: -1registry:address: spring-cloud://localhostcloud:subscribed-services: node10-dubbo-server

对比服务提供者应用 spring-cloud-dubbo-provider,除应用名称 spring.application.name 存在差异外,spring-cloud-dubbo-client-sample 新增了属性 dubbo.cloud.subscribed-services 的设置。并且该值为服务提供方应用 “spring-cloud-dubbo-provider”。

dubbo.cloud.subscribed-services : 用于服务消费方订阅服务提供方的应用名称的列表,若需订阅多应用,使用 “,” 分割。不推荐使用默认值为 “*”,它将订阅所有应用。

当应用使用属性 dubbo.cloud.subscribed-services 默认值时,日志中将会输出一行警告:

Current application will subscribe all services(size:x) in registry, a lot of memory and CPU cycles may be used, thus it’s strongly recommend you using the externalized property ‘dubbo.cloud.subscribed-services’ to specify the services

Dubbo接口调用

import com.cloud.dubbo.service.DubboService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DubboWeb {@Referenceprivate DubboService dubboService ;@GetMapping("/getInfo")public String getInfo () {return dubboService.getInfo() ;}
}

注意:@Reference也是Dubbo框架中的注解。

如上流程开发完成,先后启动dubbo-server服务和dubbo-client服务
.启动服务进行测试

分布式服务框架Dubbo集成Nacos框架实现注册中心相关推荐

  1. JEESZ架构、分布式服务:Dubbo+Zookeeper+Proxy+Restful

    分布式 分布式服务:Dubbo+Zookeeper+Proxy+Restful 分布式消息中间件:KafKa+Flume+Zookeeper 分布式缓存:Redis 分布式文件:FastDFS 负载均 ...

  2. 精选(63) 面试官:说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗?说说一次 rpc 请求的流程?

    面试题 说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗?说说一次 rpc 请求的流程? 面试官心理分析 MQ.ES.Redis.Dubbo,上来先问你一些思考性的问题.原理,比如 kaf ...

  3. 微服务 注册中心_4.微服务架构的第二个组件:注册中心

    在微服务架构下,主要有三种角色: 服务提供者(RPC Server) 服务消费者(RPC Client) 服务注册中心(Registry) RPC Server:服务提供者,启动时根据服务发布文件se ...

  4. 微服务框架 Go-Micro 集成 Nacos 实战之服务注册与发现

    作者 | 张斌斌 导读:本文主要介绍如何使用 Golang 生态中的微服务框架 Go-Micro(v2) 集成 Nacos 进行服务注册与发现.(Go-Micro 目前已经是 v3 版本,但由于某些原 ...

  5. 微服务框架Go-Micro集成Nacos实战之服务注册与发现

    简介:本文主要介绍如何使用 Golang 生态中的微服务框架 Go-Micro(v2) 集成 Nacos 进行服务注册与发现.(Go-Micro 目前已经是 v3 版本,但由于某些原因项目已经更名为 ...

  6. Spring Cloud Alibaba【Nacos 服务治理】 高可用保证:Nacos 如何有效构建注册中心集群

    上一节我们学习了 Nacos 注册中心的作用以及单点运行的方法,但是单点运行是分布式应用的大忌,在分布式架构中,任何单点都可能成为系统的瓶颈,因此在生产环境中 Nacos 都需要通过部署集群来为系统带 ...

  7. SpringCloud集成Security安全(Eureka注册中心)

    1.说明 为了保护注册中心的服务安全, 避免恶意服务注册到Eureka, 需要对Eureka Server进行安全保护, 本文基于Spring Security方案, 为Eureka Server增加 ...

  8. c++ 使用nacos_超赞!用阿里开源的Nacos做SpringCloud注册中心真贴心...

    # 什么是 Nacos? Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理. Nacos 帮助您更敏捷 ...

  9. 03 | 高可用保证:Nacos 如何有效构建注册中心集群

    如何在生产环境部署 Nacos 集群 首先介绍下之前我们在国内某互联网金融机构在项目中落地的 Nacos 集群架构图. 下面我们来解读下 Nacos 集群架构的设计要点: 微服务并不是直接通过 IP ...

最新文章

  1. 用Java调用jdbc接口连接MySQL数据库——实现对数据库的增删改查
  2. C++ Primer 5th笔记(chap 17 标准库特殊设施)正则表达式类和输入序列类型
  3. 派生类中构造函数与虚构函数的研究
  4. 4.QT中进程操作,线程操作
  5. 进程间的通信——无名管道
  6. tkinter的可视化拖拽工具_可视化越做越丑?这五个高级图表效果实现流程分享给你...
  7. 分布式ID生成的9种方法,特好用!
  8. C#LeetCode刷题之#205-同构字符串(Isomorphic Strings)
  9. NeurIPS 2021 Transformer部署难?北大华为诺亚提出Vision Transformer的后训练量化方法...
  10. 11.频域里的卷积——平滑和模糊,2D例子,低通和高通滤波器_2
  11. 获取css selector,selenium的css selector元素获取方式
  12. 启动go服务_go微服务框架go-micro深度学习 rpc方法调用过程详解
  13. Shape Correspondence and Functional Maps
  14. 查找php超时原因_php环境搭建(正确配置nginx和php)
  15. MATLAB绘图/数据的可视化
  16. 决定一台计算机运行速度快慢的配件是什么,电脑运行慢换什么配件
  17. 【题解】洛谷 P1957 口算练习题
  18. 【播放器】媒体播放器三大架构
  19. android 给图片加文字、图片水印
  20. 气死老师的作文(转贴)

热门文章

  1. 宝物志:价值近三千万钻戒秒售空,李佳琦卖出直播间最贵单品
  2. python进行聚类分析:鸢尾花(iris)代码
  3. 压缩jpg图片怎么弄?在线图片大小压缩工具怎么用?
  4. HTTP的8种请求方式及常用请求方式的解析
  5. LCD浮点数显示函数的探讨
  6. MetaMask安装使用指南
  7. 静态与静态内部类详解
  8. Linux启动重启mysql
  9. openssl 加盐_openssl passwd
  10. 八股文的终点,是刷题大冤种?还是offer收割机