微服务———服务注册与发现
一、CPA帽子理论
说到服务注册与发现,必须谈到CPA帽子理论的概念。
CPA帽子理论:
- 一致性(Cpnsistency):所有节点在相同的时间具有同样的数据;
- 可用性(Availability):保证每个请求不管成功或失败都能响应;
- 分隔容忍(Partition tolerance):系统中任意信息的丢失或失败不影响系统的继续运作。
明白以上所说的CPA帽子理论之后,接下來开始讲解关于服务注册与发现。下面试管现阶段主流的服务注册中心产品的区别:
Eureke Zookeeper Consul 所属 Netflix Apache HashiCorp CPA理论 AP CP CP 健康检测 Client Beat TCP/HTTP/Cmd/gRPC Keep Alive 负载均衡策略 Ribbon Fabio ------ 雪崩保护 有 无 无 自动注销实例 支持 支持 不支持 访问协议 HTTP HTTP/DNS TCP 监听支持 支持 支持 支持 多数据中心 支持 支持 不支持 跨注册中心同步 不支持 支持 不支持 SpringCloud集成 支持 支持 支持 Dubbo集成 不支持 支持 支持 K8S集成 不支持 支持 不支持 通信方式 peer to peer 选Leader 选Leader
二、Apache Zookeeper
Apache Zoopeeker在设计的时候就遵循CP原则,即任何时候对Zoopeeker得访问和请求能得到一直的数据结果,同时系统对网络分割具备容错性,但是Zoopeeker不能保证每次服务请求都是可达的。
优点:
1、数据一致性和分割容错。
缺点:
1、不能保证服务的可用性;
2、 若Zoopeeker集群时,当Zoopeeker中的Leader宕机了,该集群就要进行Leader的选举,由于选举Leader过程的时间较长(30~120s),在这选举的过程中,整个Zoopeeker是不可用得,可能会导致服务瘫痪。
三、Netflix Eureka
NetFlix Eureka在设计的时候就遵循AP原则,Eureka Server 也可以运行多个实例来构建集群,解决单点问题,但不同于 ZooKeeper 的选举 leader 的过程,Eureka Server 采用的是Peer to Peer 对等通信。这是一种去中心化的架构,无 master/slave 之分,每一个 Peer 都是对等的。在这种架构风格中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。每个节点都可被视为其他节点的副本。
在集群环境中如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点上,当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会在节点间进行复制(replicate To Peer)操作,将请求复制到该 Eureka Server 当前所知的其它所有节点中。
当一个新的 Eureka Server 节点启动后,会首先尝试从邻近节点获取所有注册列表信息,并完成初始化。Eureka Server 通过 getEurekaServiceUrls() 方法获取所有的节点,并且会通过心跳契约的方式定期更新。
默认情况下,如果 Eureka Server 在一定时间内没有接收到某个服务实例的心跳(默认周期为30秒),Eureka Server 将会注销该实例(默认为90秒, eureka.instance.lease-expiration-duration-in-seconds 进行自定义配置)。
当 Eureka Server 节点在短时间内丢失过多的心跳时,那么这个节点就会进入自我保护模式。
Eureka的集群中,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
- Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务;
- Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用);
- 当网络稳定时,当前实例新注册的信息会被同步到其它节点中;
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使得整个注册服务瘫痪。
四、Consul
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X)。
Consul 内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。
Consul 遵循CAP原理中的CP原则,保证了强一致性和分区容错性,且使用的是Raft算法,比zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 raft 协议要求必须过半数的节点都写入成功才认为注册成功 ;在leader挂掉了之后,重新选举出leader之前会导致Consul 服务不可用。
Consul本质上属于应用外的注册方式,但可以通过SDK简化注册流程。而服务发现恰好相反,默认依赖于SDK,但可以通过Consul Template(下文会提到)去除SDK依赖。
Consul Template
Consul,默认服务调用者需要依赖Consul SDK来发现服务,这就无法保证对应用的零侵入性。
所幸通过Consul Template,可以定时从Consul集群获取最新的服务提供者列表并刷新LB配置(比如nginx的upstream),这样对于服务调用者而言,只需要配置一个统一的服务调用地址即可。
五、NetFlix Eureka的使用
1、为什么使用Eureka
(1)Eureka是一个去中心化的注册于发现组件;
(2)Eureka采用peer to peer的通信,不会使整个注册服务瘫痪;
(3)基于REST的服务,有Server和Client。
注:什么是去中心化和中心化?
去中心化:在注册服务集群下,当其中某个一个节点挂掉之后,或者所有Eeureka Server 节点挂掉之后(客户端会缓存服务端的实例信息),整个微服务注册发现依旧运行。
中心化:例如,Zookeeper部署集群作为注册中心的时候,当其中领导者节点挂之后,会重新选举出一个新的领导者(通过Paxos算法选举)。那么在选举的期间,整个微服务集群的注册发现不可用。
建立一个springbbot醒目工程:
2、Server端
(1)pom.xml
<!--eureka服务端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
(2)yml文件
spring: application: name: springboot-eureka #应用名称 server: port: 8260 info: name: springboot-eureka eureka: #注册中心 instance: instance-id: ${spring.cloud.client.ip-address}:${server.port} prefer-ip-address: true #以IP地址注册到服务中心,相互注册使用IP地址 leaseRenewalIntervalInSeconds: 3 #加速心跳 ip-address: localhost health-check-url-path: /actuator/health #健康检测 client: registerWithEureka: false fetchRegistry: false registryFetchIntervalSeconds: 5 #eureka client间隔多久去拉取服务注册信息,默认为30秒,缩小间隔为5秒 instanceInfoReplicationIntervalSeconds: 5 #eureka client 启动之后每隔5s 向server发送配置信息 initialInstanceInfoReplicationIntervalSeconds: 5 #eureka client启动后5s后向server发送 serviceUrl: defaultZone: http://${eureka.instance.ip-address}:${server.port}/eureka/
(3)程序入口处添加@EnableEurekaServer注解。
(4)运行之后,在浏览器上输入http://localhost:8260,页面显示:
3、Client端
(1)pom.xml
<!--eureka注册中心客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
(2)yml文件
server: port: 8098 spring: application: name: springboot-mybatis #应用名称 datasource: #;连接数据库 driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@localhost:1521/ORCL username: scott password: oracle11g profiles: active: dev #表示当前的测试坏境 mybatis: #mybatis mapper-locations: classpath:com/springboot/springbootmybatis/dao/*.xml config-location=classpath: classpath:mybatis-config.xml type-aliases-package: com.springboot.springbootmybatis.entity --- spring: profiles: dev eureka: #往注册中心eureka server注册自己的Ip instance: lease-renewal-interval-in-seconds: 10 prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${server.port} ip-address: localhost health-check-url-path: /actuator/health #健康检测 client: registryFetchIntervalSeconds: 5 #eureka client间隔多久去拉取服务注册信息,默认为30秒,缩小间隔为5秒 instanceInfoReplicationIntervalSeconds: 5 #eureka client 启动之后每隔5s 向server发送配置信息 initialInstanceInfoReplicationIntervalSeconds: 5 #eureka client启动后5s后向server发送 serviceUrl: defaultZone: http://localhost:8260/eureka/
(3)程序入口处添加@EnableEurekaClient注解。
(4)运行之后,在浏览器上输入http://localhost:8260,页面显示:
项目源码地址:https://github.com/jha042120/SpringCloud