承接上文,没看完的部分接着看
ServiceConfig
//SPI的源码之前已经看过了,直接看到生成的类的代码
//ProxyFactory$Adaptive
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
//Protocol$Adaptive
private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
//省略前文看过的代码
//看到ProxyFactory$Adaptive的getInvoker方法 , 由于和前文断开, 这里的ref是暴露的服务的实现类,interfaceClass是实现的接口,registryURL为注册服务的url
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
//再对Invoker做一层包装,持有Invoker对象和this(ServiceConfig)
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
//接着看
Exporter<?> exporter = protocol.export(wrapperInvoker);
//将返回的exporter添加到ServiceConfig的成员变量exporters中
exporters.add(exporter);
}
ProxyFactory$Adaptive
public class ProxyFactory$Adaptive implements ProxyFactory {
public Object getProxy(Invoker arg0) throws RpcException {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null)
throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
com.alibaba.dubbo.common.URL url = arg0.getUrl();
String extName = url.getParameter("proxy", "javassist");
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
ProxyFactory extension = (ProxyFactory) ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension(extName);
return extension.getProxy(arg0);
}
public Object getProxy(Invoker arg0, boolean arg1) throws RpcException {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null)
throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
com.alibaba.dubbo.common.URL url = arg0.getUrl();
String extName = url.getParameter("proxy", "javassist");
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
ProxyFactory extension = (ProxyFactory) ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension(extName);
return extension.getProxy(arg0, arg1);
}
public Invoker getInvoker(Object arg0, Class arg1, com.alibaba.dubbo.common.URL arg2) throws RpcException {
if (arg2 == null) throw new IllegalArgumentException("url == null");
com.alibaba.dubbo.common.URL url = arg2;
//没有指定proxy属性,则默认为javassist
String extName = url.getParameter("proxy", "javassist");
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
//使用"javassist"获取到ProxyFactory对应的SPI扩展类,这里获取到的是包装类StubProxyFactoryWrapper
ProxyFactory extension = (ProxyFactory) ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension(extName);
//调用扩展类的getInvoker方法
return extension.getInvoker(arg0, arg1, arg2);
}
}
com.alibaba.dubbo.rpc.ProxyFactory
stub=com.alibaba.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper
jdk=com.alibaba.dubbo.rpc.proxy.jdk.JdkProxyFactory
javassist=com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory
public class StubProxyFactoryWrapper implements ProxyFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(StubProxyFactoryWrapper.class);
private final ProxyFactory proxyFactory;
private Protocol protocol;
//这里显然是JavassistProxyFactory
public StubProxyFactoryWrapper(ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
}
//这里注入的是Protocol$Adaptive
public void setProtocol(Protocol protocol) {
this.protocol = protocol;
}
@Override
public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
return proxyFactory.getProxy(invoker, generic);
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
T proxy = proxyFactory.getProxy(invoker);
if (GenericService.class != invoker.getInterface()) {
String stub = invoker.getUrl().getParameter(Constants.STUB_KEY, invoker.getUrl().getParameter(Constants.LOCAL_KEY));
if (ConfigUtils.isNotEmpty(stub)) {
Class<?> serviceType = invoker.getInterface();
if (ConfigUtils.isDefault(stub)) {
if (invoker.getUrl().hasParameter(Constants.STUB_KEY)) {
stub = serviceType.getName() + "Stub";
} else {
stub = serviceType.getName() + "Local";
}
}
try {
Class<?> stubClass = ReflectUtils.forName(stub);
if (!serviceType.isAssignableFrom(stubClass)) {
throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + serviceType.getName());
}
try {
Constructor<?> constructor = ReflectUtils.findConstructor(stubClass, serviceType);
proxy = (T) constructor.newInstance(new Object[]{proxy});
//export stub service
URL url = invoker.getUrl();
if (url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT)) {
url = url.addParameter(Constants.STUB_EVENT_METHODS_KEY, StringUtils.join(Wrapper.getWrapper(proxy.getClass()).getDeclaredMethodNames(), ","));
url = url.addParameter(Constants.IS_SERVER_KEY, Boolean.FALSE.toString());
try {
export(proxy, (Class) invoker.getInterface(), url);
} catch (Exception e) {
LOGGER.error("export a stub service error.", e);
}
}
} catch (NoSuchMethodException e) {
throw new IllegalStateException("No such constructor \"public " + stubClass.getSimpleName() + "(" + serviceType.getName() + ")\" in stub implementation class " + stubClass.getName(), e);
}
} catch (Throwable t) {
LOGGER.error("Failed to create stub implementation class " + stub + " in consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", cause: " + t.getMessage(), t);
// ignore
}
}
}
return proxy;
}
//调用JavassistProxyFactory的getInvoker
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
return proxyFactory.getInvoker(proxy, type, url);
}
private <T> Exporter<T> export(T instance, Class<T> type, URL url) {
return protocol.export(proxyFactory.getInvoker(instance, type, url));
}
}
JavassistProxyFactory
public class JavassistProxyFactory extends AbstractProxyFactory {
@Override
@SuppressWarnings("unchecked")
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
//这里动态对proxy再生成一个包装类wrapper
//这里就不更进去看了(大段的字符串拼凑成java代码,可以自行打断点进去看看生成的完整类),主要生成了invokeMethod方法,持有了proxy,判断methodName和parameterTypes,然后使用proxy调用到对应的方法
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
return new AbstractProxyInvoker<T>(proxy, type, url) {
//doInvoke来调用目标方法
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
}
生成的wrapper的invokeMethod方法
public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws java.lang.reflect.InvocationTargetException{
dubbo.test.service.TestServiceImpl w;
try{
w = ((dubbo.test.service.TestServiceImpl)$1);
} catch(Throwable e) {
throw new IllegalArgumentException(e);
}
try{
if( "test".equals( $2 ) && $3.length == 1 ) {
return ($w)w.test((java.lang.String)$4[0]);
}
} catch(Throwable e) {
throw new java.lang.reflect.InvocationTargetException(e);
}
throw new com.alibaba.dubbo.common.bytecode.NoSuchMethodException("Not found method \""+$2+"\" in class dubbo.test.service.TestServiceImpl.");
}
Protocol$Adaptive
public class Protocol$Adaptive implements Protocol {
public void destroy() {
throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
}
public int getDefaultPort() {
throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
}
public Exporter export(Invoker arg0) throws RpcException {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null)
throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
com.alibaba.dubbo.common.URL url = arg0.getUrl();
//从url中获取protocol作为扩展名称,目前还是注册流程,这里是register
String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
//获取对应的扩展类 获取到的是包装类,最终持有了RegistryProtocol
Protocol extension = (Protocol) ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);
//调用export方法
return extension.export(arg0);
}
public Invoker refer(Class arg0, com.alibaba.dubbo.common.URL arg1) throws RpcException {
if (arg1 == null) throw new IllegalArgumentException("url == null");
com.alibaba.dubbo.common.URL url = arg1;
String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
Protocol extension = (Protocol) ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);
return extension.refer(arg0, arg1);
}
}
com.alibaba.dubbo.rpc.Protocol
filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=com.alibaba.dubbo.rpc.support.MockProtocol
dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
injvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol
rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol
hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol
thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol
memcached=com.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
redis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol
rest=com.alibaba.dubbo.rpc.protocol.rest.RestProtocol
registry=com.alibaba.dubbo.registry.integration.RegistryProtocol
qos=com.alibaba.dubbo.qos.protocol.QosProtocolWrapper
ProtocolListenerWrapper
public class ProtocolListenerWrapper implements Protocol {
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
//如果是registry,该类啥都不用做
if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
return protocol.export(invoker);
}
//包装为ListenerExporterWrapper(服务发布下线通知)
return new ListenerExporterWrapper<T>(protocol.export(invoker),
//获取监听器,通知该服务发布了。
//这里啥都拿不到。
//供使用者通过spi去扩展的。Constants.EXPORTER_LISTENER_KE为"exporter.listener"
Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
.getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));
}
}
ListenerExporterWrapper
public class ListenerExporterWrapper<T> implements Exporter<T> {
private final Exporter<T> exporter;
private final List<ExporterListener> listeners;
public ListenerExporterWrapper(Exporter<T> exporter, List<ExporterListener> listeners) {
if (exporter == null) {
throw new IllegalArgumentException("exporter == null");
}
this.exporter = exporter;
this.listeners = listeners;
//通知所有listeners,服务发布了。
if (listeners != null && !listeners.isEmpty()) {
RuntimeException exception = null;
for (ExporterListener listener : listeners) {
if (listener != null) {
try {
listener.exported(this);
} catch (RuntimeException t) {
logger.error(t.getMessage(), t);
exception = t;
}
}
}
if (exception != null) {
throw exception;
}
}
}
@Override
public void unexport() {
try {
//先下线。
exporter.unexport();
} finally {
//通知所有listeners,服务下线了。
if (listeners != null && !listeners.isEmpty()) {
RuntimeException exception = null;
for (ExporterListener listener : listeners) {
if (listener != null) {
try {
listener.unexported(this);
} catch (RuntimeException t) {
logger.error(t.getMessage(), t);
exception = t;
}
}
}
if (exception != null) {
throw exception;
}
}
}
}
}
ProtocolFilterWrapper
public class ProtocolFilterWrapper implements Protocol {
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
//如果是registry,该类啥都不用做
if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
return protocol.export(invoker);
}
//调用buildInvokerChain创建过滤器链,这里的key为"service.filter",group为"provider"
return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
}
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
Invoker<T> last = invoker;
//这里根据key group拿到符合条件的Filter,可以通过spi去扩展加入自己的Filter,注意key和group
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
//从后往前构建出一个拦截器链
if (!filters.isEmpty()) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
final Invoker<T> next = last;
last = new Invoker<T>() {
@Override
public Class<T> getInterface() {
return invoker.getInterface();
}
@Override
public URL getUrl() {
return invoker.getUrl();
}
@Override
public boolean isAvailable() {
return invoker.isAvailable();
}
//next传递给下一个filter去调用
@Override
public Result invoke(Invocation invocation) throws RpcException {
return filter.invoke(next, invocation);
}
@Override
public void destroy() {
invoker.destroy();
}
@Override
public String toString() {
return invoker.toString();
}
};
}
}
return last;
}
}
QosProtocolWrapper
public class QosProtocolWrapper implements Protocol {
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
//如果是registry,先调用startQosServer
if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
//开启Qos服务端,对服务相关信息进行统计
startQosServer(invoker.getUrl());
return protocol.export(invoker);
}
//如果不是registry,该类啥都不用做
return protocol.export(invoker);
}
}
RegistryProtocol
public class RegistryProtocol implements Protocol {
@Override
public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
//启动netty服务端,获取到服务发布的对象
final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
//将url中的registry属性取出,设置到protocol属性中,再将url中的registry属性移除作为一个新的url返回
//原始originInvoker的url是registry协议头,此时的registryUrl 协议头为zookeeper(我自己用的zk做得注册中心,进行debug)
URL registryUrl = getRegistryUrl(originInvoker);
//获取注册中心对象ZookeeperRegistry。
final Registry registry = getRegistry(originInvoker);
//对原始的url去掉部分配置性的属性返回一个新的url。其中添加了一个category属性,为providers,需要向zk的providers节点下写下该url的信息
final URL registeredProviderUrl = getRegisteredProviderUrl(originInvoker);
//to judge to delay publish whether or not
boolean register = registeredProviderUrl.getParameter("register", true);
//向ProviderConsumerRegTable类中的静态属性providerInvokers建立了 服务名称和服务提供者的映射关系
ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registeredProviderUrl);
if (register) {
//这里将registeredProviderUrl(服务提供者url)的相关信息 写入到注册中心,完成服务注册。
//以ZookeeperRegistry为例,看到这里。
register(registryUrl, registeredProviderUrl);
ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
}
//overrideSubscribeUrl 为服务配置变更的url
//这里将协议头设置为provider url中添加了category属性为configurators
final URL overrideSubscribeUrl = getSubscribedOverrideUrl(registeredProviderUrl);
//这里实例化一个 配置变更时 回调的OverrideListener 。 RegistryProtocol的内部类
final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
//建立overrideSubscribeUrl 和 overrideSubscribeListener的映射关系
overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
//订阅事件。以zk来说,对应的服务路径下的configurators节点,当该节点发生变化时,回调服务提供方做配置变更。
registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
return new DestroyableExporter<T>(exporter, originInvoker, overrideSubscribeUrl, registeredProviderUrl);
}
private <T> ExporterChangeableWrapper<T> doLocalExport(final Invoker<T> originInvoker) {
//通过url生成缓存key
String key = getCacheKey(originInvoker);
//第一次进来bounds显然拿不到
ExporterChangeableWrapper<T> exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
if (exporter == null) {
synchronized (bounds) {
exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
if (exporter == null) {
//这里再把originInvoker包装为InvokerDelegete,这里getProviderUrl截取了registerUrl的协议头赋值回给protocol ,此时protocol 从registry改成了dubbo
final Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));
//这里再次调用了protocol.export, 此时不再是registry,而是dubbo,不再调用到RegistryProtocol,而最终调用到dubboProtocol
exporter = new ExporterChangeableWrapper<T>((Exporter<T>) protocol.export(invokerDelegete), originInvoker);
bounds.put(key, exporter);
}
}
}
return exporter;
}
private Registry getRegistry(final Invoker<?> originInvoker) {
URL registryUrl = getRegistryUrl(originInvoker);
//这里依然registryFactory通过set方法从spi中拿到的,为RegistryFactory$Adaptive 限于篇幅不再贴出来赘述了。
//根据协议头返回对应的注册中心对象 zk对应的是(ZookeeperRegistry)
return registryFactory.getRegistry(registryUrl);
}
private URL getRegistryUrl(Invoker<?> originInvoker) {
//获取原本的注册url(registry协议头)
URL registryUrl = originInvoker.getUrl();
if (Constants.REGISTRY_PROTOCOL.equals(registryUrl.getProtocol())) {
String protocol = registryUrl.getParameter(Constants.REGISTRY_KEY, Constants.DEFAULT_DIRECTORY);
//返回的新的url 协议头变成了原本registry属性中的值,移除了url的registry属性,
registryUrl = registryUrl.setProtocol(protocol).removeParameter(Constants.REGISTRY_KEY);
}
return registryUrl;
}
public void register(URL registryUrl, URL registedProviderUrl) {
Registry registry = registryFactory.getRegistry(registryUrl);
//调用到注册中心对象的注册方法
registry.register(registedProviderUrl);
}
}
DubboProtocol
public class DubboProtocol extends AbstractProtocol {
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
URL url = invoker.getUrl();
//根据url构造key(服务名称) 对应 exporter(服务对象)
String key = serviceKey(url);
//实例化DubboExporter
DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
//建立映射关系
exporterMap.put(key, exporter);
//处理本地存根
Boolean isStubSupportEvent = url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT);
Boolean isCallbackservice = url.getParameter(Constants.IS_CALLBACK_SERVICE, false);
if (isStubSupportEvent && !isCallbackservice) {
String stubServiceMethods = url.getParameter(Constants.STUB_EVENT_METHODS_KEY);
if (stubServiceMethods == null || stubServiceMethods.length() == 0) {
if (logger.isWarnEnabled()) {
logger.warn(new IllegalStateException("consumer [" + url.getParameter(Constants.INTERFACE_KEY) +
"], has set stubproxy support event ,but no stub methods founded."));
}
} else {
//建立服务名称和本地存根方法的映射
stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
}
}
//启动netty服务端
openServer(url);
optimizeSerialization(url);
return exporter;
}
private void openServer(URL url) {
//获取服务端启动的地址 host:port
String key = url.getAddress();
//client can export a service which's only for server to invoke
boolean isServer = url.getParameter(Constants.IS_SERVER_KEY, true);
if (isServer) {
//serverMap : 同一个地址只需要启动一个netty服务端
ExchangeServer server = serverMap.get(key);
if (server == null) {
//启动服务端,放入serverMap
serverMap.put(key, createServer(url));
} else {
// server supports reset, use together with override
server.reset(url);
}
}
}
private ExchangeServer createServer(URL url) {
// send readonly event when server closes, it's enabled by default
url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
// enable heartbeat by default (开启心跳的参数,默认为true)
url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
//默认服务端为netty
String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);
//SPI获取Transporter 看是否支持该服务端类型
if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
throw new RpcException("Unsupported server type: " + str + ", url: " + url);
//默认的编解码DubboCodec
url = url.addParameter(Constants.CODEC_KEY, DubboCodec.NAME);
ExchangeServer server;
try {
//启动服务端 ,这个requestHandler等到讲到服务调用再来看
server = Exchangers.bind(url, requestHandler);
} catch (RemotingException e) {
throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
}
str = url.getParameter(Constants.CLIENT_KEY);
if (str != null && str.length() > 0) {
Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
if (!supportedTypes.contains(str)) {
throw new RpcException("Unsupported client type: " + str);
}
}
return server;
}
}
bind
public class Exchangers {
public static ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
if (url == null) {
throw new IllegalArgumentException("url == null");
}
if (handler == null) {
throw new IllegalArgumentException("handler == null");
}
url = url.addParameterIfAbsent(Constants.CODEC_KEY, "exchange");
//spi获取Exchanger
return getExchanger(url).bind(url, handler);
}
}
public class HeaderExchanger implements Exchanger {
@Override
public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
}
}
public class Transporters {
public static Server bind(URL url, ChannelHandler... handlers) throws RemotingException {
if (url == null) {
throw new IllegalArgumentException("url == null");
}
if (handlers == null || handlers.length == 0) {
throw new IllegalArgumentException("handlers == null");
}
ChannelHandler handler;
if (handlers.length == 1) {
handler = handlers[0];
} else {
handler = new ChannelHandlerDispatcher(handlers);
}
//spi获取Transporter
return getTransporter().bind(url, handler);
}
}
public class NettyTransporter implements Transporter {
public static final String NAME = "netty";
@Override
public Server bind(URL url, ChannelHandler listener) throws RemotingException {
//启动netty服务端
return new NettyServer(url, listener);
}
@Override
public Client connect(URL url, ChannelHandler listener) throws RemotingException {
return new NettyClient(url, listener);
}
}
public class NettyServer extends AbstractServer implements Server {
public NettyServer(URL url, ChannelHandler handler) throws RemotingException {
//由父类AbstractServer 构造方法 调用子类重写的doOpen方法
//ChannelHandlers.wrap对handler对象进行包装(MultiMessageHandler HeartbeatHandler AllChannelHandler)
super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));
}
//启动netty服务端。
@Override
protected void doOpen() throws Throwable {
bootstrap = new ServerBootstrap();
bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("NettyServerBoss", true));
workerGroup = new NioEventLoopGroup(getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
new DefaultThreadFactory("NettyServerWorker", true));
final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);
channels = nettyServerHandler.getChannels();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
.childOption(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);
ch.pipeline()//.addLast("logging",new LoggingHandler(LogLevel.INFO))//for debug
//编解码
.addLast("decoder", adapter.getDecoder())
.addLast("encoder", adapter.getEncoder())
//发送接收消息
.addLast("handler", nettyServerHandler);
}
});
// bind
ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
channelFuture.syncUninterruptibly();
channel = channelFuture.channel();
}
}
AbstractRegistry
@Override
public void register(URL url) {
if (url == null) {
throw new IllegalArgumentException("register url == null");
}
if (logger.isInfoEnabled()) {
logger.info("Register: " + url);
}
//注册过的url缓存到registered
registered.add(url);
}
@Override
public void subscribe(URL url, NotifyListener listener) {
if (url == null) {
throw new IllegalArgumentException("subscribe url == null");
}
if (listener == null) {
throw new IllegalArgumentException("subscribe listener == null");
}
if (logger.isInfoEnabled()) {
logger.info("Subscribe: " + url);
}
//拿到已经监听过的该url的监听者
Set<NotifyListener> listeners = subscribed.get(url);
if (listeners == null) {
//添加监听者
subscribed.putIfAbsent(url, new ConcurrentHashSet<NotifyListener>());
listeners = subscribed.get(url);
}
listeners.add(listener);
}
protected void notify(URL url, NotifyListener listener, List<URL> urls) {
// urls是所有的对服务做修改的 , configurators节点下面可以有多个内容去修改服务
if (url == null) {
throw new IllegalArgumentException("notify url == null");
}
if (listener == null) {
throw new IllegalArgumentException("notify listener == null");
}
if ((urls == null || urls.isEmpty())
&& !Constants.ANY_VALUE.equals(url.getServiceInterface())) {
logger.warn("Ignore empty notify urls for subscribe url " + url);
return;
}
if (logger.isInfoEnabled()) {
logger.info("Notify urls for subscribe url " + url + ", urls: " + urls);
}
Map<String, List<URL>> result = new HashMap<String, List<URL>>();
for (URL u : urls) {
//判断修改服务的url 和服务提供者的url 是否匹配
if (UrlUtils.isMatch(url, u)) {
//获取category的属性值(configurators)
String category = u.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
List<URL> categoryList = result.get(category);
if (categoryList == null) {
categoryList = new ArrayList<URL>();
//建立configurators 和 修改服务的url的关系
result.put(category, categoryList);
}
categoryList.add(u);
}
}
if (result.size() == 0) {
return;
}
//建立服务提供方的url对应的缓存map (categoryNotified : configurators 和 修改服务的url)
Map<String, List<URL>> categoryNotified = notified.get(url);
if (categoryNotified == null) {
notified.putIfAbsent(url, new ConcurrentHashMap<String, List<URL>>());
categoryNotified = notified.get(url);
}
for (Map.Entry<String, List<URL>> entry : result.entrySet()) {
String category = entry.getKey();
List<URL> categoryList = entry.getValue();
//将configurators和修改服务的url放入categoryNotified
categoryNotified.put(category, categoryList);
//这里会把服务名称和对应的修改url保存到临时文件中
saveProperties(url);
//调用到 OverrideListener 的notify (限于篇幅,后文再来分析)
listener.notify(categoryList);
}
}
FailbackRegistry
@Override
public void register(URL url) {
//调用父类AbstractRegistry的register
super.register(url);
failedRegistered.remove(url);
failedUnregistered.remove(url);
try {
// Sending a registration request to the server side
//看这里,调用到子类的doRegister
doRegister(url);
} catch (Exception e) {
Throwable t = e;
//注册失败了
//判断check属性,是否需要直接抛出异常,终止程序
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true)
&& !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol());
boolean skipFailback = t instanceof SkipFailbackWrapperException;
//check为false或者异常类型为SkipFailbackWrapperException,则不终止当前程序
if (check || skipFailback) {
if (skipFailback) {
t = t.getCause();
}
throw new IllegalStateException("Failed to register " + url + " to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(), t);
} else {
logger.error("Failed to register " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
//线程池定时抓取这个集合的url重新注册。
failedRegistered.add(url);
}
}
@Override
public void subscribe(URL url, NotifyListener listener) {
super.subscribe(url, listener);
removeFailedSubscribed(url, listener);
try {
//调用到子类的doSubscribe
doSubscribe(url, listener);
} catch (Exception e) {
Throwable t = e;
List<URL> urls = getCacheUrls(url);
if (urls != null && !urls.isEmpty()) {
notify(url, listener, urls);
logger.error("Failed to subscribe " + url + ", Using cached list: " + urls + " from cache file: " + getUrl().getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/dubbo-registry-" + url.getHost() + ".cache") + ", cause: " + t.getMessage(), t);
} else {
// If the startup detection is opened, the Exception is thrown directly.
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true);
boolean skipFailback = t instanceof SkipFailbackWrapperException;
if (check || skipFailback) {
if (skipFailback) {
t = t.getCause();
}
throw new IllegalStateException("Failed to subscribe " + url + ", cause: " + t.getMessage(), t);
} else {
logger.error("Failed to subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
}
// Record a failed registration request to a failed list, retry regularly
addFailedSubscribed(url, listener);
}
}
@Override
protected void notify(URL url, NotifyListener listener, List<URL> urls) {
if (url == null) {
throw new IllegalArgumentException("notify url == null");
}
if (listener == null) {
throw new IllegalArgumentException("notify listener == null");
}
try {
//调用父类AbstractRegistry的notify
doNotify(url, listener, urls);
} catch (Exception t) {
// Record a failed registration request to a failed list, retry regularly
Map<NotifyListener, List<URL>> listeners = failedNotified.get(url);
if (listeners == null) {
failedNotified.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, List<URL>>());
listeners = failedNotified.get(url);
}
listeners.put(listener, urls);
logger.error("Failed to notify for subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
}
ZookeeperRegistry
@Override
protected void doRegister(URL url) {
try {
//将url的信息在zk创建节点,DYNAMIC默认为true,临时节点。 toUrlPath(url)将url转化为/形式,才能正常注册到zk上
zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, true));
} catch (Throwable e) {
throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
}
}
@Override
public void create(String path, boolean ephemeral) {
//如果ephemeral为false
if (!ephemeral) {
//已经创建过,直接返回
if(persistentExistNodePath.contains(path)){
return;
}
//查看zk上是否存在该url
if (checkExists(path)) {
//有的话,放入persistentExistNodePath
persistentExistNodePath.add(path);
return;
}
}
//按'/'截取递归查找zk是否含有
int i = path.lastIndexOf('/');
if (i > 0) {
create(path.substring(0, i), false);
}
if (ephemeral) {
//创建临时节点
createEphemeral(path);
} else {
//创建持久节点
createPersistent(path);
//放入persistentExistNodePath
persistentExistNodePath.add(path);
}
}
CuratorZookeeperClient。ZookeeperRegistry的构造函数,从ZookeeperTransporter$Adaptive默认获取的是curator,限于篇幅不再赘述spi相关的代码了。
public class CuratorZookeeperClient extends AbstractZookeeperClient<CuratorWatcher> {
//用的Curator操作zk
private final CuratorFramework client;
@Override
public void createEphemeral(String path) {
try {
//在zk上创建临时节点
client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
} catch (NodeExistsException e) {
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
protected void doSubscribe(final URL url, final NotifyListener listener) {
try {
//省略上半部代码
else {
List<URL> urls = new ArrayList<URL>();
//拿到url中category的值(configurators),形成zk注册中心的服务提供者的路径。
for (String path : toCategoriesPath(url)) {
//先获取已经监听过该url的监听map
ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
if (listeners == null) {
//没有,则创建一个map
zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, ChildListener>());
listeners = zkListeners.get(url);
}
//使用监听器从map获取ChildListener
ChildListener zkListener = listeners.get(listener);
if (zkListener == null) {
//拿不到
//创建一个ChildListener添加到map
//ChildListener有个childChanged方法,在zk节点变更时被调用。
listeners.putIfAbsent(listener, new ChildListener() {
@Override
public void childChanged(String parentPath, List<String> currentChilds) {
//调用父类FailbackRegistry的notify
ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
}
});
zkListener = listeners.get(listener);
}
//向zk创建该服务下的持久节点(configurators)
zkClient.create(path, false);
//启动节点监听者
List<String> children = zkClient.addChildListener(path, zkListener);
if (children != null) {
//这里将protocol属性和协议头改为empty
urls.addAll(toUrlsWithEmpty(url, path, children));
}
}
//调用父类FailbackRegistry的notify
notify(url, listener, urls);
}
} catch (Throwable e) {
throw new RpcException("Failed to subscribe " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
}
}
//创建监听器
@Override
public CuratorWatcher createTargetChildListener(String path, ChildListener listener) {
return new CuratorWatcherImpl(listener);
}
private class CuratorWatcherImpl implements CuratorWatcher {
private volatile ChildListener listener;、
public CuratorWatcherImpl(ChildListener listener) {
this.listener = listener;
}
public void unwatch() {
this.listener = null;
}
@Override
public void process(WatchedEvent event) throws Exception {
if (listener != null) {
String path = event.getPath() == null ? "" : event.getPath();
//调用ChildListener的childChanged方法
listener.childChanged(path,
// if path is null, curator using watcher will throw NullPointerException.
// if client connect or disconnect to server, zookeeper will queue
// watched event(Watcher.Event.EventType.None, .., path = null).
StringUtils.isNotEmpty(path)
//上一次的监听器使用完毕后销毁了,再次添加监听器,返回path下的子节点
? client.getChildren().usingWatcher(this).forPath(path)
: Collections.<String>emptyList());
}
}
}
@Override
public List<String> addTargetChildListener(String path, CuratorWatcher listener) {
try {
//添加监听器,返回path下的子节点
return client.getChildren().usingWatcher(listener).forPath(path);
} catch (NoNodeException e) {
return null;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}
AbstractZookeeperClient
@Override
public List<String> addChildListener(String path, final ChildListener listener) {
//先使用该路径获取到监听器
ConcurrentMap<ChildListener, TargetChildListener> listeners = childListeners.get(path);
if (listeners == null) {
//获取不到,则新建一个
childListeners.putIfAbsent(path, new ConcurrentHashMap<ChildListener, TargetChildListener>());
listeners = childListeners.get(path);
}
//再用ChildListener获取到监听器
TargetChildListener targetListener = listeners.get(listener);
if (targetListener == null) {
//获取不到,则新建一个。 createTargetChildListener掉用到子类返回监听器
listeners.putIfAbsent(listener, createTargetChildListener(path, listener));
targetListener = listeners.get(listener);
}
//调用到子类,完成zk节点订阅
return addTargetChildListener(path, targetListener);
}