- 在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过程中首先判断是否使用共享连接,如果决定使用共享连接那么就判断是否已存在未关闭的连接,如果存在那么就直接返回共享连接,如果不存在那么就创建一个连接并返回。