Dubbo source code analysis eleven: registration center

Insert picture description here

Introduction

The code of the dubbo registry is defined in the dubbo-registry module. You can see that dubbo can use consul, redis, and zookeeper to implement the registry. The default is a registry based on memory, and multicast is a registry based on broadcasting.
Insert picture description here
Registry inherits the RegistryService interface, and the RegistryService interface defines the basic operations of the registry

public interface RegistryService {
    
    

    // 注册
    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);

}

You can see that when subscribing and unsubscribing, a NotifyListener interface is passed in. When the subscription or unsubscribing action occurs, this interface will be returned.

The inheritance relationship is as shown in the figure below.
Insert picture description here
AbstractRegistry caches the contents of the registry, so as to ensure that the service can be provided normally when the registry is unavailable.

Operations such as register and subscribe are relatively simple, that is, add and delete services to the cache, and add and delete corresponding listeners to the cache.

FailbackRegistry adds a retry mechanism

How is the registry created?

The creation of the registry is realized through the factory model, and the realization of each registry corresponds to a factory class
Insert picture description here

@SPI("dubbo")
public interface RegistryFactory {
    
    

    @Adaptive({
    
    "protocol"})
    Registry getRegistry(URL url);

}

You can see that the specific factory class implementation inherits AbstractRegistryFactory. Let’s take a look at what operations AbstractRegistryFactory does?

public Registry getRegistry(URL url) {
    
    
    // 省略部分代码
    // 只有一个线程创建服务注册实例
    LOCK.lock();
    try {
    
    
        // 访问缓存
        Registry registry = REGISTRIES.get(key);
        if (registry != null) {
    
    
            return registry;
        }
        //create registry by spi/ioc
        // 是个抽象方法,子类来实现具体的创建过程
        registry = 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();
    }
}

Lock to ensure that only one registry will be created in a multi-threaded environment. There is an abstract method createRegistry, subclasses to implement the specific creation process

Zookeeper registry

Mature registry framework, which can be used in production environment

Insert picture description here
Flow Description:

  1. When the service provider starts: write your own URL address to the /dubbo/com.foo.BarService/providers directory
  2. When the service consumer starts: subscribe to the provider URL address in the /dubbo/com.foo.BarService/providers directory. And write your own URL address to the /dubbo/com.foo.BarService/consumers directory
  3. When the monitoring center starts: subscribe to the URL addresses of all providers and consumers in the /dubbo/com.foo.BarService directory.

For each interface node, there will be the following 4 child nodes (the interface node and its child nodes are persistent nodes)

Node name effect Whether the child node is a persistent node
configuators Store override or absent url for service management no
consumers Service consumer url Yes
providers Service provider url no
routers Set routing URL for service management no

The consumers node is mainly for monitoring, the other three nodes will set up listeners, when changes occur, specific events will be triggered

ZookeeperRegistry operations on the registry will be handed over to ZookeeperClient. Before version 2.7.x, Dubbo supported the implementation of two zookeeper clients, zkclient and curator, so a set of apis was extracted for the operation of zookeeper, including the event monitoring interface. 2.7.x version only supports curator client

public interface ZookeeperClient {
    
    

    void create(String path, boolean ephemeral);

    void delete(String path);

    List<String> getChildren(String path);

    List<String> addChildListener(String path, ChildListener listener);

    void addDataListener(String path, DataListener listener);

    void addStateListener(StateListener listener);

}

ZookeeperClient contains all operations on the registry and defines 3 types of listeners

  1. StateListener, monitor the connection status
  2. ChildListener, listen for all the child nodes of a node (retrieve any event)
  3. DataListener, monitor the changes of this node and its child nodes (node ​​add, delete, update, etc.)

Insert picture description here
AbstractZookeeperClient mainly performs concurrency control for adding and removing listeners. If a listener has been added to a certain path, no more will be added.

CuratorZookeeperClient mainly uses curaotr api to operate zookeeper. Its internal class CuratorWatcherImpl converts events in curator into events in dubbo .

Reference blog

[1]https://zhuanlan.zhihu.com/p/97300195

Guess you like

Origin blog.csdn.net/zzti_erlie/article/details/109408234