前面几节讲的都是单机RPC服务的模式,无论是多线程也好多进程也好,它们都只能算是单点的设计。如果节点故障,则不能再提供服务。如果要使得服务可以容忍个别节点故障仍能继续对外提供服务,则要实现分布式。
服务发现
通过服务发现技术,当RPC服务节点增加或减少时,客户端可以动态快速收到服务列表的变更信息,从而可以实时调整连接配置,这样无需重启就可以完成服务的扩容和缩容。
服务发现技术依赖于服务之间的特殊中间节点。这个节点的作用就是接受服务的注册,提供服务的查找,以及服务列表变更的实时通知功能。这可以通过Zookeeper来实现。
- 服务注册——服务节点在启动时将自己的服务地址注册到中间节点
- 服务查找——客户端启动时去中间节点查询服务地址列表
- 服务变更通知——客户端在中间节点上订阅依赖服务列表的变更事件。当依赖的服务列表变更时,中间节点负责将变更信息实时通知给客户端。
服务端的实现
代码如下:
1 | #!/usr/bin/env python3 |
服务端使用的异步IO模型,只是多了一个Zookeeper
服务的注册过程。register_zk
创建一个根节点/demo
,每个rpc服务都会在根节点下创建一个临时顺序节点,节点中的数据为:本机的ip和端口。当有某个rpc服务出现故障时,则对应的临时顺序节点也会被删除。
客户端的实现
代码如下:
1 | #!/usr/bin/env python3 |
客户端在启动时,通过get_servers
获得Zookeeper根节点/demo
的所有节点,得到的是一个服务列表,有多个IP端口对。并在/demo
节点设置了监听器watch_servers
,当有节点被添加和删除时,此监听器会被调用,用于维护__remote_servers
的服务列表。客户端调用random_server
函数随机地从__remote_servers
的服务列表地挑选任意的RPC服务节点进行连接。