在微服务理论入门篇,我们完成了两个简单的SpringBoot项目,并且使用http进行直连,本篇引入Eureka
,对项目进行改造。
Eureka是什么
什么是服务治理
在传统的RPC远程调用框架中,管理每个服务于服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务与服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
SOA 治理简介
什么是服务注册
Eureka采用了CS的架构设计,Eurake Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eurlka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系用户中各个微服务是否运行正常。
在服务注册于发现中,有一个注册中心。当服务器启动的时候,会把当前自己的服务器信息比如:服务地址、通信地址等等以别名的方式注册到注册中心。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际服务通信地址,然后再实现本地RPC调用RPC远程调用框架。核心设计思想在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心存放服务地址相关信息(接口地址)。
Eureka组件
Eureka Server
提供服务注册服务,各个微服务节点通过配置启动后,会在Eureka Server中进行注册,这阿姨那个Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client
通过注册中心进行访问,是一个java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期是30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
单机Eureka构建步骤
使用单机的Eureka来改造我们之前创建的两个SpringBoot项目。
IDEA生成Eureka Server端服务注册中心
1、创建module——cloud-erueka-server7001
2、修改maven工程的pom文件
|
3、编写配置文件
server: |
4、编写启动类
//表明这是一个Eureka Server |
5、编写完以后,启动项目,浏览器输入http://localhost:7001
就可以看到Eureka的注册中心界面了。
将支付服务整合到Eureka中
payment项目就是一个服务提供者,是一个provider。将项目注册到Eureka中需要这么几步
1、修改pom文件,将Eureka的客户端引入
<!--eureka-client--> |
2、修改yml配置
eureka: |
3、修改启动类,增加注解@EnableEurekaClient
|
4、启动项目和Eureka Server,会发现Eureka Server已经有了支付项目的注册信息
将订单项目加入到Eureka Server中
订单项目是一个消费者,主要是要调用支付服务,通过Eureka Server来调用支付服务。
1、修改pom文件,将Eureka的客户端引入
2、修改yml配置
eureka: |
3、修改启动类,增加注解@EnableEurekaClient
4、同样的步骤,我们也可以把订单项目注册到Eureka中,但是我们的调用方式还没有改变,至于怎么使用Eureka的方式调用,我们需要使用服务发现,后面会进行介绍。
Eureka服务注册流程
Eureka集群环境部署
单机版只是用来玩玩,一般都是Eureka集群。微服务RPC远程服务调用最核心得就是高可用。
集群注册原理
互相注册,相互守望。
Eureka集群环境构建
因为是集群,所以我们不可能只有一个应用在这里,但是呢为了模拟方便,新建两个Eureka Server服务分别用两个端口模拟一下集群环境。所以再新建一个Eureka Server工程,其中所有得配置与第一个相同,端口为7002。
新建好以后,在配置文件中我们需要改一下,因为我们要注册其他Eureka Server节点,相互注册。保证每个节点都有其他节点得信息。
在同一台机器上面,通过端口识别不同得Eureka Server我们在指定hostname得时候不能都指定为localhost,这样Eureka会出问题。我们需要先修改host文件,这里我使用Switch host来修改host。也可以直接在C:\Windows\System32\drivers\etc
进行修改
##########SpringCloud################# |
这样我们模拟Eureka得集群,虽然是在一台电脑不同端口,但是我们通过修改host让Eureka认为是两台机器。
然后我们修改我们得配置文件
server: |
这里需要修改的就是hostname,并且在defaultZone节点改为7002的Eureka Server,当然7002也是这么进行修改,让他们相互注册,相互守望。如果有三个或者多个,需要用逗号进行分割即可。
配置完成以后我们启动两个注册中心,然后看看是不是相互注册上了,如果注册上了就说明成功了。网址输入http://eurerka7001.com:7001/
、http://eurerka7002.com:7002/
查看DS Replicas可以看到其他节点。
- 注意:必须修改host,如果不修改host,使用loaclhost的话即使端口不一样,Eureka也会识别成一个,不会是一个集群。主要是hostname不一样即可,也可以使用一个为localhost,另一个为127.0.0.1。
将支付和订单微服务注册到Eureka集群中。
其他不需要修改,我们只需要修改yml配置文件即可。
... |
支付微服务开启多个服务,变成集群即provider集群
这里开启多个支付服务,配置集群主要是为了演示负载均衡效果。新建一个项目cloud-provider-payment8002
pom文件与8001相同。yml文件只需要修改一下端口号,然后其他的与8001相同。
为了更能体现出负载均衡,我们在controller中改一些东西,在其他服务调用的时候输出一下端口号,就能够清晰的看出,负载均衡的妙处。
|
虽然变成了集群,但是我们的订单服务还是直接连接的,并没有通过注册中心去调用,通过注册中心去调用的话需要做一些修改
1、修改一下Order项目的controller
... |
2、在注入容器的RestTemplate
上面加上负载均衡注解
|
再次调用就是通过Eureka来找支付服务。通过http://localhost/consumer/payment/get/1
我们查看到的端口号就会一会8001一会8002的变化了。
RestTemplate源码浅探
我比较好奇,他是如何识别的url的呢,我简单的看了一下源码,我们从RestTemplate
入手,在他的父类HttpAccessor
发现一段代码
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { |
创建一个ClientHttpRequest
,而这个ClientHttpRequest
是由一个工程创建的,接口ClientHttpRequestFactory
一共有很多实现类
但是我查看引用的包中并只有RibbonClientHttpRequestFactory
存在,在spring-cloud-netflix-ribbon-2.2.1.RELEASE.jar
中发现了自动配置类
RibbonAutoConfiguration
中有这么一段
|
向容器中加入RibbonClientHttpRequestFactory
,加入以后,就按照上面的ClientHttpRequest request = getRequestFactory().createRequest(url, method);
创建请求客户端,这样就可以通过Ribbon
的方式去请求Erueka
的服务,然后使用负载均衡。
至于为什么必须加上@LoadBalanced
,是因为在SpringCloud的Bean后置处理器中进行了判断
|
在初始化bean之前,如果bean有LoadBalanced
注解,那么就在bean的filter上加入exchangeFilterFunction
。
我只是简单的看了一下他是怎么调用到Ribbon的,因为代码太多以后慢慢的去看,这里仅仅是浅尝辄止。没必要深挖。
actuator微服务信息完善
主机名称:服务名称修改
在provider进行修改,需要修改yml
instance: |
访问信息有ip提示
在provider进行修改,需要修改yml
instance: |
服务发现Discovery
对于注册进Eureka里面的微服务,可以通过服务发现来获得该服务的信息
这个功能主要是用了DiscoveryClient
接口做的。使用方法如下。
... |
还需要在程序主入口加入@EnableDiscoveryClient
注解,如果有了@EnableEurekaClient
注解可以不加。
@EnableDiscoveryClient
和@EnableEurekaClient
的异同点@EnableDiscoveryClient
注解是基于spring-cloud-commons
依赖,并且在classpath中实现@EnableEurekaClient
注解是基于spring-cloud-netflix
依赖,只能为eureka作用;@EnableDiscoveryClient
和@EnableEurekaClient
共同点就是:都是能够让注册中心能够发现,扫描到该服务。@EnableEurekaClient
只适用于Eureka
作为注册中心,@EnableDiscoveryClient
可以是其他注册中心。
其实EnableDiscoveryClient
就是Springcloud的通用接口,只要实现这个就可以,适合任何服务注册中心,而EnableEurekaClient
只是Eureka
才能使用的,只有当使用Eureka作为服务注册中心的时候才有效。
使用DiscoveryClient
可以对Eureka上面的服务以及服务的信息进行发现。
Eureka自我保护
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server就会尝试保护其服务注册表中的信息,不再删除注册表中的数据,也就不会注销任何微服务。
如果在Eureka Server的首页看到以下提示,则说明Eureka进入保护模式:
- EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
导致原因
某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务得信息进行保存。为了防止EurekaClient可以正常运行,但是与EurekaServer网络不同得情况下,EuerkaServer不会立刻将EurekaClient服务剔除。这是Eureka得自我保护机制。
这个属于CAP里面得AP分支CAP 定理的含义
- 什么是CAP: CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
什么是Eureka自我保护机制
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer就会注销该实例(默认90秒)。但是当网络分区故障发生时(延迟、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变的非常危险——因为微服务本身其实是很健康的,此时本不应该注销掉这个微服务。Eureka通过”自我保护模式”来解决这个问题——当EurekaServer节点在端时间内丢失过多客户端时(可能发生网络分区故障),那么这个节点就会进入自我保护模式。
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。
它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
综上所述,自我保护模式是一种应对网络异常的安全保护措施,它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留)也不会盲目的注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
如何禁用自我保护
修改Eureka Server:
- 出厂默认,自我保护机制是开启的:
#关闭自我保护机制,保证不可用的服务被及时剔除
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000 - 关闭效果,如果2000ms以内没有心跳,直接剔除微服务。
- 出厂默认,自我保护机制是开启的:
生产者客户端EurekaClient端:
- 设置客户端向服务端发送心跳包的时间间隔
instance:
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2 - 如果两秒值内没有收到客户端的心跳,Server就会剔除客户端。
- 设置客户端向服务端发送心跳包的时间间隔
Zookeeper代替Eureka
因为Eureka2.0不再支持更新,那么再使用Eureka就有点不好了,但是我们有替代品。本节主要讲解的是zookeeper代替Eureka。
Zookeeper是一个分布式协调工具,可以实现注册中心功能。
Zookeeper安装
服务提供者项目编写
新建
Cloud-provider-payment8004
Maven项目修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud2020</artifactId>
<groupId>com.zenshin.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Cloud-provider-payment8004</artifactId>
<dependencies>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.zenshin.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot整合zookeeper客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<!--先排除自带的zookeeper3.5.3-->
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加zookeeper3.4.9版本-->
<dependency>
<groupId>org.apache.zookeeper</groupId> <!--这里可以添加任意版本,先排除掉自带的,然后引入自己的-->
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>修改yml配置文件
server:
port: 8004
# 服务别名----注册到zookeeper中心的服务名称
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 192.168.1.8:2181编写主启动类
//配置注册发现客户端,该注解用于向使用consul或者zookeeper作为注册中心时注册服务
public class PaymentMain8004 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8004.class,args);
}
}编写controller
4j
public class PaymentController
{
"${server.port}") (
private String serverPort;
"/payment/zk") (value =
public String paymentzk()
{
return "springcloud with zookeeper: "+serverPort+"\t"+ UUID.randomUUID().toString();
}
}加入配置以及服务发现客户端注解以后,启动项目就可以将项目注册进Zookeeper。
如何看到Zookeeper的信息呢?可以使用IDEA的
Zookeeper
插件,可以很直观的看到Zookeeper中注册了什么信息
可以看到Zookeeper中已经有了服务的信息,我们可以查出该节点的信息
- 这样我们的服务就注册到了zookeeper中。
Zookeeper节点类型
Znode一般分四种:临时节点、带序号的临时节点、持久节点、带序号的持久节点。
在Zookeeper中,我们注册了服务,如果我们把服务停掉,过一段时间我们再去看我们的服务,ls /services/cloud-provider-payment
就不会输出id号了,也就说明该节点在zookeeper中已经断掉了。
Zookeeper中对待节点的方式和Eureka是完全不同的,Eureka保证的是AP不同。Zookeeper保证的是强一致性,只要节点在一定时间内没有心跳了,那么这个节点我就认为是挂掉了,就会退出Zookeeper。
不会因为网络等因素等待该节点恢复。所以在Zookeeper中注册的节点都是临时节点。
将订单服务注册进zookeeper
流程与服务提供者类似,首先我们创建cloud-consumerzk-order80
编写POM文件,yml文件,这俩文件与服务提供者项目类似,只不过需要把yml的端口号改下,改成80,将服务名称改一下。
然后我们编写主启动类
|
这里我们还是使用restTemplate来操作服务提供端
|
编写controller,来操作服务提供端
|
调用端的代码与Eureka一样都是通过restTemplate进行访问。我们运行一下服务提供端与服务调用端看一下效果。
效果就是在zookeeper中有两个服务了,并且通过url能正常进行访问。
这是单机版的zookeeper的注册中心,如果是集群,只需要将所有的zookeeper地址用逗号隔开即可。
使用Consul代替Eureka
Consul简介
Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司使用GO语言进行开发的。官网简介
Consul提供了微服务系统中的服务治理、配置中心、控制总线等功能。这个功能中的每一个都可以根据需要单独使用,也可以一起使用来构建全方位的服务网格,总值Consul提供了一种完整的服务网格解决方案。
Spring Cloud Consul具有如下特性:
- 服务注册与发现:Consul客户端可以注册一个服务,如api或mysql,其他客户端可以使用Consul来发现给定服务的提供者。使用DNS或HTTP,应用程序可以很容易地找到它们所依赖的服务。
- 健康检查:Consul客户端可以提供任意数量的健康检查,或者与给定的服务相关联(“webserver是否返回200 OK”),或者与本地节点相关联(“内存利用率是否低于90%”)。操作人员可以使用此信息来监视集群的健康状况,服务发现组件可以使用此信息将流量从不健康的主机路由出去。
- 键值对存储:应用程序可以将consul的分层密钥/值存储用于任何目的,包括动态配置、特性标记、协调、领导人选举等。简单的HTTP API使其易于使用。
- 多数据中心:Consul支持多个数据中心
- 可视化的web界面
下载与安装Consul
下载 |
这样我们得consul就安装好了,但是这样只能是单机模式,-dev节点的启动不能用于生产环境,因为该模式下不会持久化任何状态,该启动模式仅仅是为了快速便捷的启动单节点consul。
输入http:// + ip+:8500 就可以访问consul的界面了。
Consul的一部分参数
参数名称 | 用途 |
---|---|
-server | 此标志用于控制代理是运行于服务器/客户端模式,每个 Consul 集群至少有一个服务器,正常情况下不超过5个,使用此标记的服务器参与 Raft一致性算法、选举等事务性工作 |
-client | 表示 Consul 绑定客户端接口的IP地址,默认值为:127.0.0.1,当你有多块网卡的时候,最好指定IP地址,不要使用默认值 |
-bootstrap-expect | 预期的服务器集群的数量,整数,如 -bootstrap-expect=3,表示集群服务器数量为3台,设置该参数后,Consul将等待指定数量的服务器全部加入集群可用后,才开始引导集群正式开始工作,此参数必须与 -server 一起使用 |
-data-dir | 存储数据的目录,该目录在 Consul 程序重启后数据不会丢失,指定此目录时,应确保运行 Consul 程序的用户对该目录具有读写权限 |
-node | 当前服务器在集群中的名称,该值在整个 Consul 集群中必须唯一,默认值为当前主机名称 |
-bind | Consul 在当前服务器侦听的地址,如果您有多块网卡,请务必指定一个IP地址(IPv4/IPv6),默认值为:0.0.0.0,也可用使用[::] |
-datacenter | 代理服务器运行的数据中心的名称,同一个数据中心中的 Consul 节点必须位于同一个 LAN 网络上 |
-ui | 启用当前服务器内部的 WebUI 服务器和控制台界面 |
-join | 该参数指定当前服务器启动时,加入另外一个代理服务器的地址,在默认情况下,如果不指定该参数,则当前代理服务器不会加入任何节点。可以多次指定该参数,以加入多个代理服务器, |
-retry-join | 用途和 -join 一致,当第一次加入失败后进行重试,每次加入失败后等待时间为 30秒 |
-syslog | 指定此标志意味着将记录 syslog,该参数在 Windows 平台不支持 |
服务提供者注册进consul
还是同样的步骤,我们新建一个工程cloud-providerconsul-payment8006
修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud2020</artifactId>
<groupId>com.zenshin.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-providerconsul-payment8006</artifactId>
<dependencies>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.zenshin.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>修改yml文件
###consul服务端口号
server:
port: 8006
spring:
application:
name: consul-provider-payment
####consul注册中心地址
cloud:
consul:
host: 192.168.0.103
port: 8500
discovery:
hostname: 192.168.0.101 #这里填写微服务的ip地址
service-name: ${spring.application.name}编写主启动类
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class,args);
}
}编写controller
4j
public class PaymentController {
"${server.port}") (
private String serverPort;
"/payment/consul") (value =
public String paymentconsul()
{
return "springcloud with consul: "+serverPort+"\t"+ UUID.randomUUID().toString();
}
}启动服务,观察consul的界面,会发现多出来一个服务,并且是健康的。
服务消费者注册进consul
编写新的服务,服务的消费者cloud-consumerconsul-order80
,pom文件与服务提供者相同,这里可以不管,yml与服务提供者一样,只是修改一下端口和应用名称即可
编写主配置类
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class,args);
}
}编写配置类,将Rest模板注入
public class ApplicationContextConfig {
public RestTemplate restTemplate()
{
return new RestTemplate();
}
}编写controller
4j
public class OrderConsulController {
public static final String INVOKE_URL = "http://consul-provider-payment";
private RestTemplate restTemplate;
"/consumer/payment/consul") (
public String paymentInfo()
{
String result =restTemplate.getForObject(INVOKE_URL+"/payment/consul",String.class);
return result;
}
}我们启动以后,就可以看到consul上面会出现Order微服务,并且通过url可以调用payment服务。
Zookeeper、Eureka、Consul异同点
组件名 | 语言 | CAP | 服务健康检查 | 对外暴露接口 | SpirngCloud集成 |
---|---|---|---|---|---|
Eureka | java | AP | 可配置支持 | http | 已集成 |
consul | go | CP | 支持 | http/dns | 已集成 |
zookeeper | java | CP | 支持 | 客户端 | 已集成 |
CAP理论
C:Consistency,强一致性
A:Availability 可用性
P:Partition tolerance 分区容错性
最多只能同时比较好的满足两个。
CAP理论关注粒度是数据,而不是整体系统设计的策略
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性、可用性和分区容错性三个需求。
因此,根据CAP原理将NoSQL数据库分成了满足CA原则、满足CP原则、满足AP原则三大类:
CA:单点集群,满足一致性、可用性的系统,通常在可扩展性上不太强大
CP:满足一致性、分区容错性的系统,通常性能不是特别高, Zookeeper/Consul
AP:满足可用性,分区容错性的系统,通常可能对一致性要求低一些。 Eureka