第一步:privoder进程停止
privoder进程停止,zk上节点被删除,consumer收到EMPTY开头的通知,然后开始销毁所有的Invoker。
1、com.alibaba.dubbo.registry.integration.RegistryDirectory#refreshInvoker
if (invokerUrls != null && invokerUrls.size() == 1 && invokerUrls.get(0) != null
&& Constants.EMPTY_PROTOCOL.equals(invokerUrls.get(0).getProtocol())) {
this.forbidden = true; // Forbid to access
this.methodInvokerMap = null; // Set the method invoker map to null
destroyAllInvokers(); // Close all invokers 开始销毁所有的Invoker
}
2、com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeChannel#close(int)
if (closed) {
return;
}
closed = true;
3、com.alibaba.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient#close(int)
if (refenceCount.decrementAndGet() <= 0) {
if (timeout == 0) {
client.close();
} else {
client.close(timeout);
}
client = replaceWithLazyClient();
}
4、com.alibaba.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient#replaceWithLazyClient
LazyConnectExchangeClient gclient = ghostClientMap.get(key);
if (gclient == null || gclient.isClosed()) {
gclient = new LazyConnectExchangeClient(lazyUrl, client.getExchangeHandler());
ghostClientMap.put(key, gclient);
}
return gclient;
第二步:provider启动
provider启动,zk节点重建,congsumer收到通知开始获取连接
1、com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#getSharedClient
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;
}
}
因为此时client实际上是LazyConnectExchangeClient类型的,它的属性也叫client,此时为null,看看它的isClose方法。
com.alibaba.dubbo.rpc.protocol.dubbo.LazyConnectExchangeClient#isClosed
public boolean isClosed() {
if (client != null)
return client.isClosed();
else
return true; // client为空,认为是关闭的。
}
2、com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#getSharedClient开始执行后续的initClient方法,创建了NettyClient等对象。
String key = url.getAddress();
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;
}
}
3、NettyClient与Bootstrap循环引用导致对象不能回收
网友评论