一. 前言
Spring Cloud是一个全家桶式的技术栈,包含了很多组件,如Eureka、Ribbon、Feign、Hystrix、Zuul等。这些组件相互协作,构建起完整的微服务系统。
二. Eureka 是什么
Eureka是Netflix的一个子模块,也是核心模块之一,它是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务系统来说是非常重要的,有了服务注册与发现,只需要使用服务的标识符(如Spring.application.name),就可以可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于Dubbo的注册中心,比如Zookeeper。
三. Eureka的基本架构
Netflix在设计Eureka时遵守的是AP原则(微服务的CAP定律)。
Spring Cloud封装了Netflix的Eureka模块来实现服务注册与发现(对比ZooKeeper)。
Eureka采用C-S架构,包含两个组件:Eureka Server和Eureka Client.Eureka Server作为服务注册中心,是提供服务注册功能的服务器。而系统中的其他服务使用Eureka Client连接到Eureka Server并维持心跳连接。这样系统维护人员可以通过Eureka Server来监控系统中各个服务是否运行正常。Spring Cloud中的一些其他模块(比如Zuul)就可以通过Eureka Server来发现系统中的其他服务,并执行相关的逻辑。
微服务系统中的各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可在界面中直观的看到.Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端也同时具备一个内置的使用轮询(round-robin)负载算法的负载均衡器.在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒).如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中移除这个节点(默认90秒).
对比下Dubbo的设计架构:
二. Eureka构建
(1)引入Eureka的Maven坐标
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
(2)在主启动类上面标注注解 @EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer // EurekaServer服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001 {
public static void main(String[] args)
{
SpringApplication.run(EurekaServer7001.class, args);
}
}
(3) 配置Eureka
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
#defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
成功启动后的界面:
此时还没有任何服务注册进来。
三. Eureka的自我保护机制
一句话概括:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该服务的信息进行保存。
默认情况下,如果Eureka Server在一定时间内(默认90秒)没有收到某个微服务实例的心跳,Eureka Server就会注销该实例.但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为就可能变得非常危险了,因为微服务本身其实是健康的,此时本不应该注销该微服务.Eureka通过"自我保护模式"来解决这个问题-当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式.一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务).当网络故障恢复后,该Eureka Server节点回自动退出自我保护模式.
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何微服务实例.当它收到的心跳数重新恢复到阈值以上时,该Eureka Server就会自动退出自我保护模式.它的这种设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例,一句话讲解就是好死不如赖活着.
综上,自我保护模式是一种应对网络异常的安全保护措施,他的架构哲学是宁可同时保留所有的微服务(健康的和不健康的都会保留),也不盲目注销任何健康的服务,这种机制可以让Eureka集群更加的健壮,稳定.
在Spring Cloud中,可以使用eureka.server.enable-self-preservation=false禁用自我保护模式,但一般不建议这么做.
四. Eureka的集群配置
集群就是在不同的机器上部署相同的服务,对外做一个超大的运算整体。
(1)为了在单机上模拟集群的效果,需要修改本机hosts文件。
找到C:\Windows\System32\Drivers\etc\hosts,修改域名映射配置添加进hosts文件。
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
(2)Eureka Server端配置
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
defaultZone: http://eureka7002.com:7002/eureka/
server:
port: 7002
eureka:
instance:
#hostname: localhost 单机版
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
defaultZone: http://eureka7001.com:7002/eureka/ #多个Eureka Server之间一“,”分隔
五. 作为服务注册中心,Eureka比Zookeeper好在哪?
(1) Eureka-AP VS Zookeeper-CP
传统的ACID. A(Atomicity):原子性 C(Consistency):一致性 I(Isolation):独立性 D(Durability):持久性
CAP:C(Consistency):强一致性 A(Availability):可用性 P(Partition tolerance):分区容错性