zoukankan      html  css  js  c++  java
  • 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);
        }
  • 相关阅读:
    安装SSH、配置SSH无密码登录 ssh localhost
    ubuntu系统中java开发环境的搭建
    大二暑假周进度报告之七
    大二暑假周进度报告之六
    Hadoop2.9.1安装教程_环境Ubuntu_VMware安装
    大二暑假周进度报告之五
    DDWRT路由WEB认证之Wiwiz
    在不支持jffs2的DD-WRT里安装Wiwiz的3种方法
    nodogsplash在指定网络下工作
    使用wiwiz实现WiFi无线热点认证与计费网关
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12517231.html
Copyright © 2011-2022 走看看