Dubbo Provider暴露源码分析
Dubbo服务端的服务暴露及初始化
org.apache.dubbo.config.spring.ServiceBean#afterPropertiesSet开始spring 容器初始化好属性后,回调这个方法开始初始化Provider- 前面一堆是初始化
ApplicationConfig、Module、Registry(注册中心)、ConfigCenter(配置中心)、Monitor(监控中心)、Metrics(监控项)、Service(服务bean) - 接着找到
org.apache.dubbo.config.ServiceConfig#doExportUrls;- 主要看
org.apache.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol - 这个方法主要是构建Invoker代理,然后用
Exporter<?> exporter = protocol.export(wrapperInvoker);通过SPI加载默认DubboProtocol. - 进入
org.apache.dubbo.rpc.DubboProtocol#export之后我们看到一个openServer调用,初始化一个Server - 进入
org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#openServer,主要调用createServer - 进入
org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#createServer,调用了一个静态方法Exchangers#bind() - 进入
org.apache.dubbo.remoting.exchange.Exchangers#bind,入参是当前要暴露服务的URL和一个requestHandler, requestHandler实现在org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#requestHandler里 - 进入
Exchangers#bind,调用了org.apache.dubbo.remoting.exchange.Exchangers#getExchanger(org.apache.dubbo.common.URL)获取当前暴露服务URL的个性化Exchanger配置,默认加载org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger - 进入
HeaderExchanger,有两个方法实现分别为bind和connect,看样子一个事用于Server端暴露服务,一个事用于Client来请求服务 - 主要看
org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger#bind,调用了Transporters#bind(),这里吧requestHandler进行包装成了一个org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#HeaderExchangeHandler - 进入
org.apache.dubbo.remoting.Transporters#bind(),看到默认加载的是nett4的org.apache.dubbo.remoting.transport.netty4.NettyTransporter#bind(),而这个实现主要是new了一个org.apache.dubbo.remoting.transport.netty4.NettyServer#NettyServer,到此一个Provider的Invoker代理就绑定到NettyServer里可以对外提供服务了 - 在
NettyServer的构造方法中,调用了org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers#wrap,将HeaderExchangeHandler进行一个Dispatcher的分发,默认实现是org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher,除此之外还有ConnectionOrderedDispatcher、DirectDispatcher、ExecutionDispatcher、MessageOnlyDispatcher,这里不做展开 - 在AllDispatcher中的dispatch实现是
AllChannelHandler,所有类型的请求都可以接受处理 - 进入
org.apache.dubbo.remoting.transport.dispatcher.all.AllChannelHandler#received,我们看到它将接收到的请求丢到一个ExecutorService线程池中异步处理,这里就是Dubbo线程处理的核心了 - 我们回到第6步,这里说到默认的handler是
org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#requestHandler, 这个requestHandler被6.3包装成了org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#HeaderExchangeHandler - 进入
org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#HeaderExchangeHandler,这是NIO请求的处理handler,我们了解NIO的Channel是双向通信的,所以当接收到请求时和响应时都会进入到received,当出现异常时进入caught- 我们先来看
org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#received,主要判断是请求还是响应,如果是请求判断是否是否有响应,如果是towWay通信,即有响应结果的请求,进入org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#handleRequest - 在这里调用了一开始传入的requestHandler#reply,实在在
org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter,这里就是具体调用找到具体要请求的Provider的Invoker,异步请求并返回一个Feature,然后在当前received方法中进行异步等待,等待响应结果完成send进channel进行响应
- 我们先来看
- 主要看
- 发布到注册中心