dubbo的服務引用流程

整體流程

服務引用流程與暴露流程一樣,每一個標籤都對應一個解析類

例如:referenceBean對應的解析類是com.alibaba.dubbo.config.spring.ReferenceBean

@Autowired註解通過調用 get方法從容器中獲取refence標籤中配置的實體類

// 繼承了RefenceConfig,實現了FactoryBean
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {

    private static final long serialVersionUID = 213195494150089726L;

    private transient ApplicationContext applicationContext;

    public ReferenceBean() {
        super();
    }

    public ReferenceBean(Reference reference) {
        super(reference);
    }

    ......
    
    // 工廠Bean
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        SpringExtensionFactory.addApplicationContext(applicationContext);
    }
    // <dubbo:reference id="queryService" interface="com.yaoyagang.api.QueryService"
    //retries="0" timeout="3000" check="false"/>
    @Override
    public Object getObject() throws Exception {
        // 調用get方法從容器中獲取refence標籤中配置的實體類
        return get();
    }

    @Override
    public Class<?> getObjectType() {
        // 獲取com.alibaba.dubbo.config.ReferenceConfig
        return getInterfaceClass();
    }

    @Override
    @Parameter(excluded = true)
    public boolean isSingleton() {
        return true;
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public void afterPropertiesSet() throws Exception {
       ......
    }

    @Override
    public void destroy() {
        // do nothing
    }

從註冊中心遠程獲取privode的接口

referenceConfig中的init方法中:
// 消費者需要引用的接口類名,urls配置中心的url
invoker = refprotocol.refer(interfaceClass, urls.get(0));

調用RegistryProtocol的refer方法

public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
     ......   
     // 獲取註冊中心的信息
     Registry registry = this.registryFactory.getRegistry(url);
     ......
     
     // 調用doRefer方法
     // registry:註冊中心的地址,type:需要引用的service類,url:註冊中心的地址
     this.doRefer(this.cluster, registry, type, url) 
}

private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {
     
    RegistryDirectory<T> directory = new RegistryDirectory(type, url);
    directory.setRegistry(registry);
    directory.setProtocol(this.protocol);
     // 訂閱註冊中心的服務者提供的服務
    directory.subscribe(subscribeUrl.addParameter("category","providers,configurators,routers"));

}

訂閱服務會進去到DubboProtocol,調用refer方法

@Override
    public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
        optimizeSerialization(url);
        // serviceType:服務提供者service類,url:註冊中心地址,getClients獲取客戶端
        // 獲取執行者
        DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);
        invokers.add(invoker);
        return invoker;
    }


private ExchangeClient[] getClients(URL url) {
     // 根據連接數獲取客戶端,底層是通過netty實現的
     ExchangeClient[] clients = new ExchangeClient[connections];
}

獲取到執行者之後,返回到RegistryProtocol中的doRefer方法

private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {
        RegistryDirectory<T> directory = new RegistryDirectory(type, url);
        directory.setRegistry(registry);
        directory.setProtocol(this.protocol);
        ......
        // 訂閱
        directory.subscribe(subscribeUrl.addParameter("category", "providers,configurators,routers"));
        // 獲取執行者:invoker中有服務提供者的相關信息
        Invoker invoker = cluster.join(directory);
        // 把invoker放入註冊表中
        // subscribeUrl爲消費者的相關信息
        ProviderConsumerRegTable.registerConsumer(invoker, url, subscribeUrl, directory);
        return invoker;
    }
    .....
}

註冊表ProviderConsumerRegTable

public class ProviderConsumerRegTable {
    // 提供者Url以及其他信息
    public static ConcurrentHashMap<String, Set<ProviderInvokerWrapper>> providerInvokers = new ConcurrentHashMap<String, Set<ProviderInvokerWrapper>>();
    // 消費者Url以及消費者的代理對象Invoke
    public static ConcurrentHashMap<String, Set<ConsumerInvokerWrapper>> consumerInvokers = new ConcurrentHashMap<String, Set<ConsumerInvokerWrapper>>();
    ......
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章