服务提供方需要发布服务,由于应用系统的复杂性,服务的数量、类型会不断膨胀;对于服务消费方,它最关心如何获取到它所需要的服务。而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,既需要提供服务,又需要消费服务。通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。我们看下dubbo官网的截图:
服务提供方发布服务到服务注册中心
服务消费方从服务注册中心订阅服务
服务消费方调用已经注册的可用服务
我们将会实现本地注册中心和基于Zookeeper的注册中心,因此定义一个IServiceDiscovery服务发现接口,该接口里面有注册服务、取消注册服务、更新服务、订阅服务、取消订阅服务、查询所有已注册服务名称、根据服务名称查询服务实例集合:
我们可以订阅感兴趣的服务,因此我们定义一个事件监听器接口:
然后定义一个抽象类AbstractServiceEventListener,当服务发生变化的时候,触发相应的事件:
然后我们定义一个抽象类AbstractServiceDiscovery:
在该抽象类中,我们将订阅的服务事件放到了一个Map中,接着看下notify方法,该方法会在注册服务、更新服务、卸载服务时触发相应的事件:
然后我们看下具体的注册中心实现,先来看本地注册中心:
我们这里定义了一个REGISTER_CENTER变量,用来保存注册的服务信息,然后看下registerLocal方法:
我们解析地址信息,解析出来主机和端口,然后构造一个ServiceInstance实例,接着调用registerService方法进行服务注册:
registerService方法就是简单的将服务保存到REGISTER_CENTER变量中,然后调用notify方法触发相应的事件,本地REGISTER_CENTER变量保存了服务注册信息,因此该类中的其他接口都是操作该变量获取相应的数据,这里就不多介绍了。
我们看下基于Zookeeper的注册中心:
我们定义了Zookeeper的默认地址为"localhost:2181",然后定义了处理序列化的变量instanceSerializer,还有一个ServiceDiscovery的变量(curator库的类)
我们看下start方法,该方法将会连接到Zookeeper:
DevilsConstant.ZK_BASE_PATH是配置的服务注册zk基础路径:
MetaInfo是payload,记录了负载均衡类型、ha策略、权重、分组等信息:
然后看下注册服务、卸载服务、更新服务等方法的实现,只需要简单的委托调用serviceDiscovery变量的方法就可以:
最后看下childEvent方法,实现TreeCacheListener接口需要实现该方法,我们这里首先拿到节点数据信息serviceInstance,然后开始匹配当前的事件类型treeCacheEvent.getType,最后调用notify方法执行相应的事件操作:
本小节到此结束,下一节将会介绍相应的服务属性配置。