天天看點

Dubbo Consumer 共享連接配接說明

Dubbo Consumer 共享連接配接說明
  • 在Dubbo的consumer和provider的服務引用過程中,兩者之間存在多個服務引用。
  • 在consumer和provider之間建立的連接配接,存在共享連接配接和非共享連接配接兩種情況,預設情況下使用的是共享連接配接。
  • 在consumer和provider之間的所有reference和service是共享的同一個連接配接。

共享連接配接

public class DubboProtocol extends AbstractProtocol {

    public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
        optimizeSerialization(url);
        // create rpc invoker.
        DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);
        invokers.add(invoker);
        return invoker;
    }

    private ExchangeClient[] getClients(URL url) {
        // whether to share connection
        boolean service_share_connect = false;
        int connections = url.getParameter(Constants.CONNECTIONS_KEY, 0);
        // // 如果是共享連接配接
        if (connections == 0) {
            service_share_connect = true;
            connections = 1;
        }

        ExchangeClient[] clients = new ExchangeClient[connections];
        for (int i = 0; i < clients.length; i++) {
            // 如果存在共享連接配接則通路通過getSharedClient()傳回共享連接配接
            if (service_share_connect) {
                clients[i] = getSharedClient(url);
            } else {
                clients[i] = initClient(url);
            }
        }
        return clients;
    }

    private ExchangeClient getSharedClient(URL url) {
        String key = url.getAddress();
        // 如果存在共享連接配接且連接配接可用則直接傳回
        ReferenceCountExchangeClient client = referenceClientMap.get(key);
        if (client != null) {
            if (!client.isClosed()) {
                client.incrementAndGetCount();
                return client;
            } else {
                referenceClientMap.remove(key);
            }
        }

        locks.putIfAbsent(key, new Object());
        synchronized (locks.get(key)) {
            if (referenceClientMap.containsKey(key)) {
                return referenceClientMap.get(key);
            }

            ExchangeClient exchangeClient = initClient(url);
            client = new ReferenceCountExchangeClient(exchangeClient, ghostClientMap);
            referenceClientMap.put(key, client);
            ghostClientMap.remove(key);
            locks.remove(key);
            return client;
        }
    }
}           
  • 在refer過程中首先判斷是否使用共享連接配接,如果決定使用共享連接配接那麼就判斷是否已存在未關閉的連接配接,如果存在那麼就直接傳回共享連接配接,如果不存在那麼就建立一個連接配接并傳回。

繼續閱讀