链接有哪几种类型?有什么作用?
dubbo的链接有2类,第一类是共享链接。consumer&每一个provider实例有一个多服务共享的链接。第二类是独享链接,consumer&每一个provider实例的每一个暴露的服务有独立的链接。
在初始化client时,会根据是否配置connections来决定链接是哪一类。
参考代码DubboProtocol:
private ExchangeClient[] getClients(URL url) { // whether to share connection boolean useShareConnect = false; int connections = url.getParameter(CONNECTIONS_KEY, 0); List<ReferenceCountExchangeClient> shareClients = null; // if not configured, connection is shared, otherwise, one connection for one service if (connections == 0) { useShareConnect = true; /* * The xml configuration should have a higher priority than properties. */ String shareConnectionsStr = url.getParameter(SHARE_CONNECTIONS_KEY, (String) null); connections = Integer.parseInt(StringUtils.isBlank(shareConnectionsStr) ? ConfigUtils.getProperty(SHARE_CONNECTIONS_KEY, DEFAULT_SHARE_CONNECTIONS) : shareConnectionsStr); shareClients = getSharedClient(url, connections); } ExchangeClient[] clients = new ExchangeClient[connections]; for (int i = 0; i < clients.length; i++) { if (useShareConnect) { clients[i] = shareClients.get(i); } else { clients[i] = initClient(url); } } return clients; }
在具体执行时,如果有多个链接,会循环使用。
参考DubboInvoker:
@Override protected Result doInvoke(final Invocation invocation) throws Throwable { RpcInvocation inv = (RpcInvocation) invocation; final String methodName = RpcUtils.getMethodName(invocation); inv.setAttachment(PATH_KEY, getUrl().getPath()); inv.setAttachment(VERSION_KEY, version); ExchangeClient currentClient; if (clients.length == 1) { currentClient = clients[0]; } else { currentClient = clients[index.getAndIncrement() % clients.length]; } ...... }
当声明consumer or reference时,标注了connections的会创建多个独享的链接。该值如果为0,则会基于provider的地址值创建共享的链接。
默认情况下,consumer&每个provider之间都只有一个共享的链接。但是如果存在不同服务的报文大小差别很大(比如有些请求报文十几KB,有些不到1KB),可以使用独享链接,降低网络IO对QPS的影响。
如果报文大小基本差不多,响应也很迅速,瓶颈不再网络而在服务端并发处理能力的情况下, 共享链接就足够用。