Dubbo源码-09-RegistryFactory
作用
远程配置中心的实现
- ZookeeperRegistryFactory 实现zookeeper的远程配置中心,获取zk的读取zkClient
一 接口声明
@SPI("dubbo")
public interface RegistryFactory {
/**
* Connect to the registry
* <p>
* Connecting the registry needs to support the contract: <br>
* 1. When the check=false is set, the connection is not checked, otherwise the exception is thrown when disconnection <br>
* 2. Support username:password authority authentication on URL.<br>
* 3. Support the backup=10.20.153.10 candidate registry cluster address.<br>
* 4. Support file=registry.cache local disk file cache.<br>
* 5. Support the timeout=1000 request timeout setting.<br>
* 6. Support session=60000 session timeout or expiration settings.<br>
*
* @param url Registry address, is not allowed to be empty
* @return Registry reference, never return empty value
*/
@Adaptive({"protocol"})
Registry getRegistry(URL url);
}
从注解就可以看出来,默认实现是dubbo,扩展点是URL中的协议protocol
二 类图
很明显在抽象类中定义了抽象方法,子类关注具体的getRegistry()的实现,而使用哪个子类实现取决于URL中的协议
三 抽象
// AbstractRegistryFactory.java
@Override
public Registry getRegistry(URL url) {
url = url.setPath(RegistryService.class.getName())
.addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName())
.removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY);
/**
* url
* - zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=native-provider&dubbo=2.0.2&interface=com.alibaba.dubbo.registry.RegistryService&pid=38892&qos.port=22222×tamp=1669559112755
* key
* - zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService
*/
String key = url.toServiceStringWithoutResolving();
// Lock the registry access process to ensure a single instance of the registry
LOCK.lock();
try {
Registry registry = REGISTRIES.get(key);
if (registry != null) {
return registry;
}
registry = this.createRegistry(url); // 实现在子类
if (registry == null) {
throw new IllegalStateException("Can not create registry " + url);
}
REGISTRIES.put(key, registry);
return registry;
} finally {
// Release the lock
LOCK.unlock();
}
}
三 实现
1 ZookeeperRegistryFactory
@Override
public Registry createRegistry(URL url) {
return new ZookeeperRegistry(url, zookeeperTransporter);
}
// ZookeeperRegistry.java
public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) {
// zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=native-provider&dubbo=2.0.2&interface=com.alibaba.dubbo.registry.RegistryService&pid=39657&qos.port=22222×tamp=1669560173930
super(url);
if (url.isAnyHost()) {
throw new IllegalStateException("registry address == null");
}
String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT); // dubbo
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
group = Constants.PATH_SEPARATOR + group;
}
this.root = group; // /dubbo
/**
* 创建zk的客户端 后续操作客户端对zk进行读写
* 实现有2个
* - ZkclientZookeeperTransporter
* - CuratorZookeeperTransporter
* 默认是CuratorZookeeperTransporter
*/
zkClient = zookeeperTransporter.connect(url);
// zk监听器
zkClient.addStateListener(new StateListener() {
@Override
public void stateChanged(int state) {
if (state == RECONNECTED) {
try {
recover();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
});
}
// CuratorZookeeperTransporter.java
@Override
public ZookeeperClient connect(URL url) {
return new CuratorZookeeperClient(url);
}
// CuratorZookeeperClient.java
public CuratorZookeeperClient(URL url) {
super(url);
try {
int timeout = url.getParameter(Constants.TIMEOUT_KEY, 5000);
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
.connectString(url.getBackupAddress())
.retryPolicy(new RetryNTimes(1, 1000))
.connectionTimeoutMs(timeout);
String authority = url.getAuthority();
if (authority != null && authority.length() > 0) {
builder = builder.authorization("digest", authority.getBytes());
}
client = builder.build();
client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
@Override
public void stateChanged(CuratorFramework client, ConnectionState state) {
if (state == ConnectionState.LOST) {
CuratorZookeeperClient.this.stateChanged(StateListener.DISCONNECTED);
} else if (state == ConnectionState.CONNECTED) {
CuratorZookeeperClient.this.stateChanged(StateListener.CONNECTED);
} else if (state == ConnectionState.RECONNECTED) {
CuratorZookeeperClient.this.stateChanged(StateListener.RECONNECTED);
}
}
});
client.start();
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}