本文主要是介绍MicroService--ZooKeeper,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
背景:
现在后端使用微服务方式开发,然而分布式系统带来了很多问题,比如:
现在公司开发了一个RPC框架来给各组开发人员使用,为了支持高并发,OrderService部署了4份,也就意味着每个客户端保存了一份服务提供者的列表,但是这个列表在配置文件中是写死的,意味着如果某台服务器down了,客户端并不知道,依然会尝试访问。
客户端与服务提供者紧耦合,要解决这个问题,要加一个中间层。
理解RPC:
RPC指的是远程过程调用,就是不熟在服务器A的应用要调用服务器B上的函数,由于不在一个内存空间,所以需要使用网络来表达怎么调用以及要调用的内容。RPC就是要像调用本地函数一样去调用远程函数。
所以使用注册中心,它保存了能提供服务的名称,以及URL。首先这些服务会在注册中心进行注册,当客户端来查询的时候,只需要给出名称,注册中心就会给出一个URL。
这个注册中心类似于一个上帝的角色,他可以了解全局有那些服务提供者,以及这些提供者的状态。
所有的客户端再访问服务前,都需要向这个注册中心进行询问,已获得最新的地址。
注册中心一般是树形结构,每个服务下面有若干节点,每个节点标识服务的实例。
注册中心和各个服务实例直接建立Session,要求他们定期发送心跳,一旦特定时间收不到新桃,则认为实例挂了,删除该实例
实例间 Job协调问题:
三个Job的功能相同,部署在三个不同的机器上,要求同一时刻只有一个可以运行,也就是如果有一个down了的话,需要在剩下的两个汇总选举出Master,继续工作。
这三个实例Job需要相互协调:(两种策略)
1 使用共享数据库表。数据库主键不能冲突,可以让三个Job向表中插入同样的数据,谁成功谁就是Master。缺点是如果抢到Master的节点挂了,则记录永远存在,其他的节点无法插入数据。所以必须加上定期更新的机制。
2 让Job在启动之后,去注册中心注册,也就是创建一个树节点,谁成功谁是Master.这样如果节点删除了,就开始新一轮争抢。
同样实时知道是否当前的Master还需要存活,所以注册中心需要与各个机器通信。
如果机器没有死掉,只是与注册中心通讯断了,所以长时间连接不上,然后注册中心吧树节点master删除,另外两台机器重新抢到了Master,但是原先的Master并不知道,所以还在努力的运行自己的JOB,这就冲突了。
解决方法当然是机器,也需要感知到自己与注册中心连接断了,然后停止JOB,等到再次与注册中心连接上,才知道自己已经不是Master了。
分布式锁:
多个机器上的系统同时对某个资源进行争抢,如果在同一个进程中加了锁就可以了,但是现在是分布式的,只能使用分布式锁
解决方法:
1 使用Mster选举的方式,让大家去抢,谁能抢到就创建一个/distribute_lock节点,读完以后就删除,让大家再来抢,缺点是某个系统可能多次抢到,不够公平。
2 让每个系统在注册中心/distribute_lock 下创建子节点,然后编号。每个系统检查自己的编号,谁小认为谁持有了锁,
系统1操作完成以后,就可以吧process_01删除了,在创建一个新的节点process_04,此时是process_02最小了,所以认为系统2持有了锁。
如此循环下去,分布式锁就实现了
注册中心的高可用性:
如果注册中心只有一台机器,一旦挂了,整个系统就down了,所以需要多台机器来保证高可用性。 ZooKeeper提供了类似的解决方案,它已经实现了树形结构在国泰机器之间的可靠复制:
Session:标识节点与ZooKeeper之间的会话,ZooKeeper会定期发送心跳,如果特定时间收不到心跳则结束会话
Znode: 树形结构中的每个节点就叫znode,
可以分为:
永久znode:除非主动删除,否则一直存在
临时znode:Session一旦结束就删除
顺序znode:也就是分布式锁汇总的process_01,process_02
Watch: 客户节点可以监控Znode的变化,同时Znode变化了以后也会通知客户节点,这样其他节点可以继续争抢创建节点。
总结: ZooKeeper用来干什么。
ZooKeeper is a centralized service for maintaining configuration information, naming ,providing distributed synchronization, and providing group services.
ZooKeeper主要可以,配置管理,名字服务,提供分布式同步以及集群管理。
配置管理:
Zookeeper 这种服务,它使用Zab这种一致性协议来提供一致性。有很多开源项目使用Zookeeper来维护配置,比如在HBase中,客户端就是连接一个Zookeeper,获得必要的HBase集群的配置信息,然后才可以进一步操作。还有在开源队列Kafka中,也使用ZooKeeper来维护broker的信息。在Alibaba开源的SOA框架Dubbo中也使用Zookeeper管理一些配置来实现服务治理。
名字服务:
通过网络访问一个系统,我们得知道对方的IP地址,但是IP地址对人非常不友好,这个时候我们就需要使用域名来访问。但是计算机是不能是别域名的。怎么办呢?如果我们每台机器里都备有一份域名到IP地址的映射,这个倒是能解决一部分问题,但是如果域名对应的IP发生变化了又该怎么办呢?于是我们有了DNS这个东西。我们只需要访问一个大家熟知的(known)的点,它就会告诉你这个域名对应的IP是什么。在我们的应用中也会存在很多这类问题,特别是在我们的服务特别多的时候,如果我们在本地保存服务的地址的时候将非常不方便,但是如果我们只需要访问一个大家都熟知的访问点,这里提供统一的入口,那么维护起来将方便得多了。
分布式锁:
ZooKeeper是一个分布式协调服务。我们可以利用Zookeeper来协调多个分布式进程之间的活动,比如在一个分布式环境中,为了提高可靠性,我们的集群的每台服务器上都部署这同样的服务。但是,一件事情如果集群中的每个服务都进行的话,那相互之间就要协调,编程将非常复杂。如果我们只让一个服务进行操作,那么又存在单点。还有一种做法就是使用分布式锁,在某个时刻只让一个服务区干活,当这台服务处问题的时候锁释放,立即fail over 到另外的服务。很多分布式系统都这么做,采用Leader Election(leader选举)。比如HBase的Master就是采用这种机制。
集群管理:
在分布式集群中,经常会由于各种原因,比如硬件故障,软件故障,网络问题,有些节点会进进出出。有新的节点加入,也有老的节点退出。集群中其他机器需要感知这种变化,然后根据这种变化做出对应的决策。一个分布式存储系统,有一个中央控制节点负责存储的分配,当有新的存储进来的时候,要根据现在集群目前的状态来分配存储节点。这个时候我们需要感知到集群目前的状态。 另外,一个分布式SOA构架中,服务是一个集群提供的,当消费者访问某个服务时,就需要采用某种机制发现现在有那些节点可以提供该服务(也成为服务发现,比如Alibaba开源的SOA框架Dubbo就采用了Zookeeper作为服务发现的底层机制)还有开源Kafka队列也采用了Zookeeper作为Cosnumer的上下线管理。
这篇关于MicroService--ZooKeeper的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!