Dubbo2.7源码分析-如何发布服务 (6)

其中没有transporter参数,所以就使用netty。然后dubbo就去查找netty对应的是哪个Transporter,结果找到是NettyTransporter。

package org.apache.dubbo.remoting.transport.netty4; //省略导入部分 public class NettyTransporter implements Transporter { public static final String NAME = "netty"; @Override public Server bind(URL url, ChannelHandler listener) throws RemotingException { return new NettyServer(url, listener); } @Override public Client connect(URL url, ChannelHandler listener) throws RemotingException { return new NettyClient(url, listener); } }

NettyTransporter很简单,只有两个方法,一个用于开启服务,一个用于连接服务。到这里已经明白了Dubbo是如何发布一个服务的。

我们再进一步看下NettyServer的构造函数

public NettyServer(URL url, ChannelHandler handler) throws RemotingException { super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME))); }

可以看出其调用父类的构造函数,并传入url和handler的包裹类。handler的包裹类有哪些呢,进去看一看。

public static ChannelHandler wrap(ChannelHandler handler, URL url) { return ChannelHandlers.getInstance().wrapInternal(handler, url); } protected ChannelHandler wrapInternal(ChannelHandler handler, URL url) { return new MultiMessageHandler(new HeartbeatHandler(ExtensionLoader.getExtensionLoader(Dispatcher.class) .getAdaptiveExtension().dispatch(handler, url))); }

注意到有一个接口Dispatcher,其自适应插件类是AllDispatcher,AllDispatcher的dispatch方法返回AllChannelHandler实例(此实例会将所有请求做为任务放入线程池中处理),在此实例基础上又包裹了HeartbeatHandlerMultiMessageHandler
NettyServer会将MultiMessageHandler层层往上传到其父类AbstractPeer。

我们来回忆一下正向流程

从ServiceConfig发布registryURL开始(见doExportUrlsFor1Protocol方法)
1.ServiceConfig生成服务实例的代理工厂类JavassistProxyFactory(ProxyFactory SPI默认代理工厂类)并包裹到DelegateProviderMetaDataInvoker(此类记录代理工厂类和服务信息ServiceBean(标签对应的类))
2.由于registryURL的protocol协义是registry,所以会加载RegistryProtocol(Protocol类的外面都包裹了ProtocolFilterWrapper和ProtocolListenerWrapper,下面不再特殊说明),并传入上一步的invoker。
3.RegistryProtocol又找到DubboProtocol,也会带上Invoker(此时的Invoker包含上一次的Invoker并带有服务地址(dubbo://IP:端口/服务接口全称?参数=xxx))。

所以requestHandler又会调用正向传过来的Invoker,经过ProtocolFilterWrapper和ProtocolListenerWrapper,最终调用到服务实现类相应的方法。

最后以一张图总结:

Dubbo2.7源码分析-如何发布服务

标识为SPI的类,是可以动态加载的。图片看不清楚的话,请查看原图。

再简单说下接收到请求后的处理流程:NettyServer接收到请求后,交给NettyServerHandler处理,NettyServerHandler转交给NettyServer的父类AbstractPeer处理,AbstractPeer又交给MultiMessageHandler处理,这样就开始了handler链的处理,handler的终点是HeaderExchangerHandler,HeaderExchangerHandler调用DubboProtocol传过来的成员变量requestHandler调用相应的服务类方法,然后得到结果,调用NettyServerHandler传过来的NettyChannel发送结果到Client。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxzjg.html