RPC注册中心-- 检测服务是否存活
=注册中心的职责,发现服务,监控服务变更状态、健康检查。
需要做到的是:总能通过把request发送到一个有效的Service Provider那里,或者没有可用的Service Provider时,及时告知服务调用方。
服务注册中心检测服务是否存活的方法:长连接 + 轮询(心跳)。注册中心主要提供所有服务注册信息的中心存储,同时负责将服务注册信息的更新通知实时的Push给服务消费者(主要是通过Zookeeper的Watcher机制来实现的)。
服务提供者作为服务的提供方将自身的服务信息注册到服务注册中心中。服务信息包含:
▪ 隶属于哪个系统
▪ 服务的IP,端口
▪ 服务的请求URL
▪ 服务的权重等等
服务消费者主要职责如下:
1. 服务消费者在启动时从服务注册中心获取需要的服务注册信息
2. 将服务注册信息缓存在本地
3. 监听服务注册信息的变更,如接收到服务注册中心的服务变更通知,则在本地缓存中更新服务的注册信息
4. 根据本地缓存中的服务注册信息构建服务调用请求,并根据负载均衡策略(随机负载均衡,Round-Robin负载均衡等)来转发请求
5. 对服务提供方的存活进行检测(监听zk节点事件),如果出现服务不可用的服务提供方(zk临时节点不存在),将从本地缓存中剔除。
服务消费者只在自己初始化以及服务变更时会依赖服务注册中心,在此阶段的单点故障通过Zookeeper集群来进行保障。在整个服务调用过程中,服务消费者不依赖于任何第三方服务。
通过zookeeper如何做服务存活检测:
使用到zookeeper的特性是:临时节点,心跳检活;
服务提供者主动发心跳,或注册中心向服务提供者发心跳。
服务提供者的服务改变,主动推送给注册中心。
ZK的临时节点的特性,可以让不同的进程都在ZK的一个指定节点下创建临时子节点,不同的进程直接可以根据这个临时子节点来判断对应的进程是否存活。通过这种方式,检测和被检测系统直接并不需要直接相关联,而是通过监听ZK上的某个节点进行判断,大大减少了系统耦合。
服务消费者会去监听相应路径(zk某个节点),一旦路径上的数据有任务变化(增加或减少),zookeeper都会通知服务消费方服务提供者地址列表已经发生改变,从而进行更新。
Zookeeper注册节点的掉线自动重新注册及测试方法
一个服务通常不只部署在一个机器上。需要做到的是:总能通过把request发送到一个有效的Service Provider那里,或者没有可用的Service Provider时,及时告知服务调用方。
当一个Service Provider从Zookeeper上退出后,我们一定不会再用它,但是,我们如何保证一个Service Provider还存活的情况下,都能处于可服务的状态呢?例如,Service Provider 1的程序工作一直很稳定,但是某天由于ISP的原因,它和Zookeeper之间的网络中断了5分钟,于是Zookeeper会无法向它发送心跳包,最终Zookeeper会认为session expired了,从而会把它注册的临时节点给移除掉(必须是注册临时节点啊,要不然当Service Provider挂了之后节点还在,岂不出乱子了)。移除掉之后,问题就来了:5分钟后中断的网络恢复正常了,Service Provider 1的程序也一直没有死掉,它又可以serving了,但是由于它在Zookeeper中注册的节点没了,所以Service User通过connection pool是永远也无法向Service Provider 1发送request的,于是所有的request还是都发到了Service Provider 2那里,造成它的负载一直很大,系统的处理能力减弱。
因此,为了避免这种问题,我们需要在Service Provider中提供Zookeeper掉线自动重新注册的功能。
要实现这种功能,需要添加一个实现了ConnectionStateListener接口的类,并应用到CuratorFramework对象上。(Curator库是一个绝好的选择。它是Netflix开发的一套开源软件。)