# 注册中心
dubbo中可以使用的注册中心有:MulticastRegistry、RedisRegistry、ZookeeperRegistry,分别是组播注册中心、redis保存数据的注册中心以及zookeeper保存数据的注册中心;
在实现上,注册中心实现了Registry接口
```
URL getUrl();
boolean isAvailable();
void destroy();
void register(URL url); // 注册服务
void unregister(URL url); // 取消注册
void subscribe(URL url, NotifyListener listener); // 订阅符合条件的已注册数据,当有注册数据变更时自动推送
void unsubscribe(URL url, NotifyListener listener); // 取消订阅
List<URL> lookup(URL url); // 查询符合条件的已注册数据,与订阅的推模式相对应,这里为拉模式,只返回一次结果。
```
AbstractRegistry是一个抽象类,实现了Registry接口,内部时注册中心的基本功能,有几个主要属性
```
private final Set<URL> registered = new ConcurrentHashSet<URL>();// 保存注册的服务
private final ConcurrentMap<URL, Set<NotifyListener>> subscribed = new ConcurrentHashMap<URL, Set<NotifyListener>>();// 保存订阅url的通知事件
private final ConcurrentMap<URL, Map<String, List<URL>>> notified = new ConcurrentHashMap<URL, Map<String, List<URL>>>();// 保存通知的url列表
private URL registryUrl; // 注册中心的url
```
AbstractRegistry实现接口的逻辑如下:
```
public void register(URL url) // 将url保存到registered集合中
public void unregister(URL url) // 从registered集合中移除url
public void subscribe(URL url, NotifyListener listener) // 订阅服务时将 url和监听事件保存到subscribed变量中,一个url有多个监听事件
public void unsubscribe(URL url, NotifyListener listener) // 取消订阅,移除subscribed中的监听事件
```
FailbackRegistry也是一个抽象类,继承了AbstractRegistry类,主要用来失败重试。
## 发布服务
1. RegistryProtocol发布服务时,会首先创建Registry注册中心或获取已经初始化的注册中心
2.
## 引用服务
1. RegistryProtocol发布服务时,会首先创建Registry注册中心或获取已经初始化的注册中心
2. 从引用的服务获取url,使用注册中心的register注册`consumer://xxx/xxx?xxx`,在zookeeper上创建`/dubbo/接口名/consumers/consumer://xxx`节点。
3. 之后,使用注册中心subscribe方法订阅服务消费者`consumer://xxx/xxx?xxx`,根据url中category的值创建以下几个节点,并添加监听事件
```
[/dubbo/com.alibaba.dubbo.demo.DemoService/providers,
/dubbo/com.alibaba.dubbo.demo.DemoService/configurators,
/dubbo/com.alibaba.dubbo.demo.DemoService/routers]
```
```
-| MockClusterInvoker
-|FailoverClusterInvoker
—| Directory 返回一个Invoker列表
```
```
RegistryDirectory的notify中会
invoker = new InvokerDelegete<T>(protocol.refer(serviceType, url), url, providerUrl);
protocol是DubboProtocol,refer时会创建client
client = Exchangers.connect(url, requestHandler);
Exchangers.connect(url, requestHandler);
HeaderExchanger connect()
Transporters connect()
NettyTransporter connect()
```
```
cluster.join(directory);
|- MockClusterInvoker
|— FailoverClusterInvoker
|- RegistryDirectory
directory.list(invocation);会返回Invoker列表,然后根据调用
```