转自:https://my.oschina.net/huangyong/blog/345164

        在 Java 世界里,有一种技术可以实现“跨虚拟机”的调用,它就是 RMI(Remote Method Invocation,远程方法调用)。例如,服务A 在 JVM1 中运行,服务B 在 JVM2 中运行,服务A 与 服务B 可相互进行远程调用,就像调用本地方法一样,这就是 RMI。在分布式系统中,我们使用 RMI 技术可轻松将 服务提供者(Service Provider)与 服务消费者(Service Consumer)进行分离,充分体现组件之间的弱耦合,系统架构更易于扩展。使用 ZooKeeper 可轻松解决 RMI 调用过程中所涉及的问题。

         ZooKeeper 是 Hadoop 的一个子项目,用于解决分布式系统之间的数据一致性问题,如果读者尚不了解 ZooKeeper 的工作原理与使用方法,可以通过以下链接来了解:

        本文假设读者已经对 ZooKeeper 有一定了解的前提下,对 RMI 的高可用性问题提供一个简单的解决方案。

        要想解决 RMI 服务的高可用性问题,我们需要利用 ZooKeeper 充当一个 服务注册表(Service Registry),让多个 服务提供者(Service Provider)形成一个集群,让 服务消费者(Service Consumer)通过服务注册表获取具体的服务访问地址(也就是 RMI 服务地址)去访问具体的服务提供者。如下图所示:

初识Zookeeper

需要注意的是,服务注册表并不是 Load Balancer(负载均衡器),提供的不是“反向代理”服务,而是“服务注册”与“心跳检测”功能。

利用服务注册表来注册 RMI 地址,这个很好理解,那么“心跳检测”又如何理解呢?说白了就是通过服务中心定时向各个服务提供者发送一个请求(实际上建立的是一个 Socket 长连接),如果长期没有响应,服务中心就认为该服务提供者已经“挂了”,只会从还“活着”的服务提供者中选出一个做为当前的服务提供者。

也许读者会考虑到,服务中心可能会出现单点故障,如果服务注册表都坏掉了,整个系统也就瘫痪了。看来要想实现这个架构,必须保证服务中心也具备高可用性。

ZooKeeper 正好能够满足我们上面提到的所有需求。

  1. 使用 ZooKeeper 的临时性 ZNode 来存放服务提供者的 RMI 地址,一旦与服务提供者的 Session 中断,会自动清除相应的 ZNode。
  2. 让服务消费者去监听这些 ZNode,一旦发现 ZNode 的数据(RMI 地址)有变化,就会重新获取一份有效数据的拷贝。
  3. ZooKeeper 与生俱来的集群能力(例如:数据同步与领导选举特性),可以确保服务注册表的高可用性。
        通过本文,我们尝试使用 ZooKeeper 实现了一个简单的 RMI 服务高可用性解决方案,通过 ZooKeeper 注册所有服务提供者发布的 RMI 服务,让服务消费者监听 ZooKeeper 的 Znode,从而获取当前可用的 RMI 服务。此方案局限于 RMI 服务,对于任何形式的服务(比如:WebService),也提供了一定参考

        总结: ZooKeeper从设计模式角度来看,是一个基于服务提供者(Service Provider)模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受服务提供者(Service Provider)的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的那些服务提供者(Service Provider)做出相应的反应,从而实现集群中类似 Master/Slave 管理模式,关于 Zookeeper 的详细架构等内部细节可以阅读 Zookeeper 的源码。

相关文章: