服务注册与发现的来源
首先,服务注册与发现是来自于微服务架构的产物。
在传统的服务架构中,服务的规模处于运维人员的可控范围内。当部署服务的多个节点时,一般使用静态配置的方式实现服务信息的设定。而在微服务应用中,服务实例的数量和网络地址都是动态变化的,这对系统运维提出了巨大的挑战。
而且服务集群的跨度很大、数量很多(数以百计甚至更多),为保障系统的正常运行,必然需要有一个中心化的组件完成对各个服务的整合,即将分散于各处的服务进行汇总,汇总的信息可以是服务器的名称、地址、数量等,并且这些服务器组件还拥有被监听功能等(服务发现)。
这就是服务注册与发现的来源,在微服务架构中,服务注册与发现组件是必不可少的,常用的服务协调器有:Eureka、Zookeeper,ANS、Dubbo、Etcd等。
下面我分别从:服务注册发现主要解决的问题、特点、原理和Zookeeper的实现方式四个维度详细介绍。
服务注册与发现主要解决的问题
在一个分布式系统中,服务注册与发现组件主要解决两个问题:服务注册和服务发现。
1.服务注册
服务实例将自身服务信息注册到注册中心。这部分服务信息包括服务所在主机IP和提供服务的Port,以及暴露服务自身状态以及访问协议等信息。
2.服务发现
服务实例请求注册中心获取所依赖服务信息。服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务。
除此之外,服务注册与发现需要关注监控服务实例运行状态等问题。
3.监控
微服务应用中,服务处于动态变化的情况,需要一定机制处理无效的服务实例。一般来讲,服务实例与注册中心在注册后通过心跳的方式维系联系,一旦心跳缺少,对应的服务实例会被注册中心剔除。
关系调用说明:
- 服务生产者启动时,向服务注册中心注册自己提供的服务
- 服务消费者启动时,在服务注册中心订阅自己所需要的服务
- 注册中心返回服务提供者的地址信息个消费者
- 消费者从提供者中调用服务
服务注册与发现的特点
1.高可用
由多个服务节点构成,就算有些节点挂掉也不影响正常运行,避免了单点故障。
2.方便配置
本身是一个分布式,一致性的 k-v 存储系统。提供方启动的时候将自身配置信息向协调器中进行注册,提供方下线的时候向协调器进行反注册。
3.可监控
提供心跳机制,如果对方程序意外挂掉,没有进行反注册,协调器也会超时剔除不可用的提供方。
服务注册发现的实现方式
我从服务注册发现实现的早期到现在主流的Zookpeer介绍,这样可以更加直观的了解到对应的优劣势,更有利于今后的选型升级。
1. DNS(早期)
DNS作为服务注册发现的一种方案,它比较简单。只要在DNS服务上,配置一个DNS名称与IP对应关系即可。定位一个服务只需要连接到DNS服务器上,随机返回一个IP地址即可。由于存在DNS缓存,所以DNS服务器本身不会成为一个瓶颈。
这种基于Pull的方式不能及时获取服务的状态的更新(例如:服务的IP更新等)。
如果服务的提供者出现故障,由于DNS缓存的存在,服务的调用方会仍然将请求转发给出现故障的服务提供方。
2.Zookeeper
Zookeeper是google开源的在Java语言上实现的分布式协调服务,是Hadoop和Hbase的重要组件,提供了数据/发布订阅、负载均衡、分布式同步等功能。
Zookeeper也是基于主从架构,搭建了一个可高扩展的服务集群,其服务架构如下:
- Leader-Server:Leader负责进行投票的发起和决议,更新系统中的数据状态
- Server:Server中存在两种类型:Follower和Observer。其中Follower接受客户端的请求并返回结果(事务请求将转发给Leader处理),并在选举过程中参与投票;Observer与Follower功能一致,但是不参与投票过程,它的存在是为了提高系统的读取速度
- Client:请求发起方,Server和Client之间可以通过长连接的方式进行交互。如发起注册或者请求集群信息等。
3.Dubbo
Dubbo的服务发现模块基于zookeeper实现。
Eureka是spring cloud之下一个专门负责微服务服务注册和发现的组件,Eureka就是为了服务发现而设计的。是Dubbo对应的概念的一个部分。
4.Eureka
Eureka 是 Netflix 出品的用于实现服务注册和发现的工具。 Spring Cloud 集成了 Eureka,并提供了开箱即用的支持。其中, Eureka 又可细分为 Eureka Server 和 Eureka Client。
上图是来自eureka的官方架构图,这是基于集群配置的eureka
– 处于不同节点的eureka通过Replicate进行数据同步
– Application Service为服务提供者
– Application Client为服务消费者
– Make Remote Call完成一次服务调用
服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。
当服务注册中心Eureka Server检测到服务提供者因为宕机、网络原因不可用时,则在服务注册中心将服务置为DOWN状态,并把当前服务提供者状态向订阅者发布,订阅过的服务消费者更新本地缓存。
Zookeeper与Eureka的区别
想要了解Zk与eureka的区别首先要知道CAP定理
CAP定理
1. Zookeeper保证CP
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。
2.Eureka保证AP
Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。