dubbo源码阅读-远程暴露(七)之Exchangers

接口定义

复制代码
@SPI(HeaderExchanger.NAME)//缺省值为header

public interface Exchanger {

    /**
     * bind.
     *
     * @param url
     * @param handler
     * @return message server
     */
    @Adaptive({Constants.EXCHANGER_KEY}) //带有参数exchanger
    ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException;

    /**
     * connect.
     *
     * @param url
     * @param handler
     * @return message channel
     */
    @Adaptive({Constants.EXCHANGER_KEY})//带参数exchanger
    ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException;

}
复制代码

 

类图

 

 

说明

我们接着服务暴露开始看《dubbo源码阅读-服务暴露(七)之远程暴露(dubbo)》

复制代码
private ExchangeServer createServer(URL url) {
        // send readonly event when server closes, it's enabled by default
        // // 服务器关闭时发送readonly事件,默认情况下启用
        url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
        // enable heartbeat by default
        //// 心跳默认间隔一分钟
        url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
        //// 获得远程通讯服务端实现方式,默认用netty
        String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);

        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 {
            // <1>启动服务器并暴露服务 内部会启动netty服务暴露服务
            server = Exchangers.bind(url, requestHandler);
        } catch (RemotingException e) {
            throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
        }
        // // 获得客户端侧设置的远程通信方式 client
        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;
    }
复制代码

Exchangers

com.alibaba.dubbo.remoting.exchange.Exchangers#bind

<1>bind

复制代码
 /**
     * 这个时候的
     * @param url 暴露的url
     * @param handler 为com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#requestHandler 成员变量 匿名实现
     * @return
     * @throws RemotingException
     */
    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");
        /**
         *<2>获取Exchange
         *<5>调用bind 方法
         */
        return getExchanger(url).bind(url, handler);
    }
复制代码

<2>getExchanger

com.alibaba.dubbo.remoting.exchange.Exchangers#bind

->

com.alibaba.dubbo.remoting.exchange.Exchangers#getExchanger

public static Exchanger getExchanger(URL url) {
        //从参数获得exchanger 如果没有取默认header
        String type = url.getParameter(Constants.EXCHANGER_KEY, Constants.DEFAULT_EXCHANGER);
        //<3>SPI获取对应的Exchange
        return getExchanger(type);
    }

<3>getExchanger

com.alibaba.dubbo.remoting.exchange.Exchangers#bind

->

com.alibaba.dubbo.remoting.exchange.Exchangers#getExchanger

->

com.alibaba.dubbo.remoting.exchange.Exchangers#getExchanger

 public static Exchanger getExchanger(String type) {
        //SPI扩展点  默认取的header 所以这里返回的是 com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger
        return ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension(type);
    }

HeaderExchanger

<5>bind

com.alibaba.dubbo.remoting.exchange.Exchangers#bind

->

com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger#bind

复制代码
  @Override
    public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
        //1. handler 会再次经过2层包装,增加功能 注:源头handler是com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#requestHandler
        ChannelHandler h  = new DecodeHandler(new HeaderExchangeHandler(handler));
        //2. Transports 操作会启动netty 监听端口,配置序列化实现,https://www.cnblogs.com/LQBlog/p/12517551.html#autoid-4-0-0
        Server s = Transporters.bind(url,h);
        /**
         * <6>HeaderExchangeServer: 会对nettyServer 进行包装, 主要增加2个功能:
         *
         *     a. 对channel进行 空闲时间检测,超过则关闭连接,节省资源。
         *
         *     b. 如果server关闭,则发送消息给client端,不再发送请求到该server。
         */
        return new HeaderExchangeServer( s);
    }
复制代码
posted @   意犹未尽  阅读(449)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
历史上的今天:
2019-03-18 elasticsearch-搜索建议(八)
点击右上角即可分享
微信分享提示