Dubbo服务暴露(二)------ 服务启动,注册,监听

承接上文,没看完的部分接着看
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);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值