dubbo 2.6.2 DubboProtocol openServer(URL url) 做了什么

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) {
    ExchangeServer server = serverMap.get(key);
    if (server == null) {
        serverMap.put(key, createServer(url));
    } else {
        // server supports reset, use together with override
        server.reset(url);
    }
}

 

先判断 URL 参数isserver 是不是true 默认是true

根据URL 得到key (ip:端口号) 从缓存获取server对象 没有则创建

有则调用reset方法

先分析createServer(url)

server = Exchangers.bind(url, requestHandler);

url = url.addParameterIfAbsent(Constants.CODEC_KEY, "exchange");//不存在则添加参数codec=exchange

return getExchanger(url).bind(url, handler);

 

public static Exchanger getExchanger(URL url) {

        String type =

                   url.getParameter(Constants.EXCHANGER_KEY, Constants.DEFAULT_EXCHANGER);

        return getExchanger(type);

}//获取参数exchanger 默认值header

ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension(type) //由于type默认是header 所以得到的Exchanger实现类是HeaderExchanger

return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));

这是的handler变成了 DecodeHandler{ HeaderExchangeHandler {DubboProtocol 内部类实现}}

Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))
getTransporter().bind(url, handler);
public static Transporter getTransporter() {

    return ExtensionLoader.getExtensionLoader(Transporter.class).getAdaptiveExtension();

}
@SPI("netty")

public interface Transporter
 

由于Transporter 的spi是netty 所以Transporter实现是com.alibaba.dubbo.remoting.transport.netty. NettyTransporter 不是netty4那个包里面的

return new NettyServer(url, listener);
super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));

ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME))//添加threadname = DubboServerHandler-127.0.0.1:20880  可以设置threadname参数值来改变DubboServerHandler这个字符串 然后返回一个新的URL

ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME))
 
return ChannelHandlers.getInstance().wrapInternal(handler, url);
return new MultiMessageHandler(new HeartbeatHandler(ExtensionLoader.getExtensionLoader(Dispatcher.class)

        .getAdaptiveExtension().dispatch(handler, url)));
 

ExtensionLoader.getExtensionLoader(Dispatcher.class) .getAdaptiveExtension()

Dispatcher 接口上的spi名称是all 可以确定实现类是AllDispatcher

return new AllChannelHandler(handler, url);

此时的handler变成了MultiMessageHandler{ HeartbeatHandler { DecodeHandler{ HeaderExchangeHandler {DubboProtocol 内部类实现}}

}}

AllChannelHandler 继承与WrappedChannelHandler

public WrappedChannelHandler(ChannelHandler handler, URL url) {

    this.handler = handler;

    this.url = url;

    executor = (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);



    String componentKey = Constants.EXECUTOR_SERVICE_COMPONENT_KEY;

    if (Constants.CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(Constants.SIDE_KEY))) {

        componentKey = Constants.CONSUMER_SIDE;

    }

    DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();

    dataStore.put(componentKey, Integer.toString(url.getPort()), executor);

}

获取ThreadPool 类的实现再调用.getExecutor(url)获得一个线程执行器 配置是根据URL 的配置,URL的配置是来源于发布协议的配置

然后把执行器添加到DataStore实现类的缓存当中

我们回到创建NettyServer实例这段代码:

super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));

分析完了ChannelHandlers.wrap这个方法干的事情就是返回了一个

AllChannelHandler{

         MultiMessageHandler{

                 HeartbeatHandler {

                           DecodeHandler{

                                    HeaderExchangeHandler {

                                               DubboProtocol 内部类实现

                                     }

                            }

                   }

         }

}

看看super执行了什么

this.url = url;

this.handler = handler;
this.codec = getChannelCodec(url);

this.timeout = url.getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);

this.connectTimeout = url.getPositiveParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT);
localAddress = getUrl().toInetSocketAddress();



String bindIp = getUrl().getParameter(Constants.BIND_IP_KEY, getUrl().getHost());

int bindPort = getUrl().getParameter(Constants.BIND_PORT_KEY, getUrl().getPort());

if (url.getParameter(Constants.ANYHOST_KEY, false) || NetUtils.isInvalidLocalHost(bindIp)) {

    bindIp = NetUtils.ANYHOST;

}

bindAddress = new InetSocketAddress(bindIp, bindPort);

this.accepts = url.getParameter(Constants.ACCEPTS_KEY, Constants.DEFAULT_ACCEPTS);

this.idleTimeout = url.getParameter(Constants.IDLE_TIMEOUT_KEY, Constants.DEFAULT_IDLE_TIMEOUT);

try {

    doOpen();

    if (logger.isInfoEnabled()) {

        logger.info("Start " + getClass().getSimpleName() + " bind " + getBindAddress() + ", export " + getLocalAddress());

    }

} catch (Throwable t) {

    throw new RemotingException(url.toInetSocketAddress(), null, "Failed to bind " + getClass().getSimpleName()

            + " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);

}

//fixme replace this with better method

DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();

executor = (ExecutorService) dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY, Integer.toString(url.getPort()));
 

getChannelCodec(url) 是根据url参数codec的值通过spi来获取 没有配置就是dubbo

根据文件配置

dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec

可以知道codec  = DubboCountCodec实例

executor 就是创建AllChannelHandler根据发布协议的配置创建的缓存实例

还有就是一堆配置参数的初始化 就不一一说明

然后执行了doOpen()

final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);

创建了一个nettyHandler 传入的是当前实例  那么nettyHandler 如下:

NettyHandler {

         NettyServer{

                   AllChannelHandler{

                            MultiMessageHandler{

                                    HeartbeatHandler {

                                              DecodeHandler{

                                                       HeaderExchangeHandler {

                                                                  DubboProtocol 内部类实现

                                                        }

                                               }

                                      }

                            }

                   }

         }

}

最后将nettyHandler 添加到了netty服务器的ChannelPipeline 中 netty框架就不介绍了

最后得到的DubboProtocol 里面缓存的server 实例就是

HeaderExchangeServer{//这个类主要负责心跳相关的功能

         NettyServer{//没有额外功能就是对提供netty服务器的打开和关闭和一些便利方法

         }

}

接下来看看DubboProtocol.reset(URL)做了什么

调用了NettyServer集成与AbstractServer那么执行了AbstractServer.reset

更改了NettyServer 的一些配置信息和吧当前URL的参数添加到了NettyServer的url属性的URL中(参数覆盖合并)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值