RocketMQ 中的 NettyRemotingAbstract 类

在 RocketMQ 的架构体系中,NettyRemotingAbstract 类占据着举足轻重的地位,它是 RocketMQ 基于 Netty 实现网络通信的抽象基础类,为上层的 RemotingServer 和 RemotingClient 提供了核心的通信处理逻辑。深入理解 NettyRemotingAbstract 类,有助于我们把握 RocketMQ 消息收发、连接管理以及线程模型等关键机制。

一、NettyRemotingAbstract 类的作用

NettyRemotingAbstract 类主要负责封装与 Netty 相关的网络通信操作,将复杂的网络编程细节抽象化,使得 RocketMQ 的 Remoting 模块能够专注于消息协议处理和业务逻辑实现。它管理着 Netty 的 Channel、EventLoopGroup 等核心组件,提供了统一的消息发送、接收和处理接口,同时处理网络连接的建立、断开以及异常情况。

二、核心组件与初始化

(一)主要核心属性

 /**
     * Semaphore to limit maximum number of on-going one-way requests, which protects system memory footprint.
     * 限制 one-way请求的最大数量
     */
    protected final Semaphore semaphoreOneway;

    /**
     * Semaphore to limit maximum number of on-going asynchronous requests, which protects system memory footprint.
     * 限制异步请求的最大数量
     */
    protected final Semaphore semaphoreAsync;

    /**
     * This map caches all on-going requests.
     * 通过remotingServer发送出去的所有请求都会缓存到这个map中 来等待请求的响应
     */
    protected final ConcurrentMap<Integer /* opaque */, ResponseFuture> responseTable =
        new ConcurrentHashMap<Integer, ResponseFuture>(256);

    /**
     * This container holds all processors per request code, aka, for each incoming request, we may look up the
     * responding processor in this map to handle the request.
     * key为请求id value值为一个pair pair里有对应的请求处理组件 以及请求处理组件对应的线程池
     */
    protected final HashMap<Integer/* request code */, Pair<NettyRequestProcessor, ExecutorService>> processorTable =
        new HashMap<Integer, Pair<NettyRequestProcessor, ExecutorService>>(64);

    /**
     * Executor to feed netty events to user defined {@link ChannelEventListener}.
     * netty网络事件处理的组件
     *
     */
    protected final NettyEventExecutor nettyEventExecutor = new NettyEventExecutor();

    /**
     * The default request processor to use in case there is no exact match in {@link #processorTable} per request code.
     * 默认的请求处理组件
     */
    protected Pair<NettyRequestProcessor, ExecutorService> defaultRequestProcessor;

    /**
     * SSL context via which to create {@link SslHandler}.
     * 用于进行安全网络加密通信 是属于netty的一个组件
     */
    protected volatile SslContext sslContext;

    /**
     * custom rpc hooks
     * 自定义的rpc 回调的钩子
     */
    protected List<RPCHook> rpcHooks = new ArrayList<RPCHook>();
 

(二)消息编解码与处理器

  1. 编解码器

NettyRemotingAbstract 类使用自定义的编解码器将 RocketMQ 的消息协议(如 RemotingCommand)与字节流进行相互转换。编解码器的实现基于 Netty 的 ByteToMessageDecoder 和 MessageToByteEncoder,确保消息在网络传输过程中的正确格式。

a.编码
   /**
     * 针对内容进行编码
     * @return
     */
    public ByteBuffer encode() {
        // 1> header length size
        int length = 4;

        // 2> header data length
        byte[] headerData = this.headerEncode();
        length += headerData.length;

        // 3> body data length
        if (this.body != null) {
            length += body.length;
        }

        ByteBuffer result = ByteBuffer.allocate(4 + length);

        // length
        result.putInt(length);

        // header length
        result.putInt(markProtocolType(headerData.length, serializeTypeCurrentRPC));

        // header data
        result.put(headerData);

        // body data;
        if (this.body != null) {
            result.put(this.body);
        }

        result.flip();

        return result;
    }

   /**
     * 进行头编码的操作
     * @return
     */
    private byte[] headerEncode() {
        // 自定义的headers 放入到extfiled的Map中
        this.makeCustomHeaderToNet();
        //判断序列化的类型是哪种 采用对应的序列化方式
        if (SerializeType.ROCKETMQ == serializeTypeCurrentRPC) {
            return RocketMQSerializable.rocketMQProtocolEncode(this);
        } else {
            return RemotingSerializable.encode(this);
        }
    }

    public static byte[] rocketMQProtocolEncode(RemotingCommand cmd) {
        // String remark
        byte[] remarkBytes = null;
        int remarkLen = 0;
        if (cmd.getRemark() != null && cmd.getRemark().length() > 0) {
            remarkBytes = cmd.getRemark().getBytes(CHARSET_UTF8);
            remarkLen = remarkBytes.length;
        }

        // HashMap<String, String> extFields
        //把扩展字段给序列化成字节数组
        byte[] extFieldsBytes = null;
        int extLen = 0;
        if (cmd.getExtFields() != null && !cmd.getExtFields().isEmpty()) {
            extFieldsBytes = mapSerialize(cmd.getExtFields());
            extLen = extFieldsBytes.length;
        }
        //计算总长度
        int totalLen = calTotalLen(remarkLen, extLen);

        ByteBuffer headerBuffer = ByteBuffer.allocate(totalLen);
        // int code(~32767)
        headerBuffer.putShort((short) cmd.getCode());
        // LanguageCode language
        headerBuffer.put(cmd.getLanguage().getCode());
        // int version(~32767)
        headerBuffer.putShort((short) cmd.getVersion());
        // int opaque
        headerBuffer.putInt(cmd.getOpaque());
        // int flag
        headerBuffer.putInt(cmd.getFlag());
        // String remark
        if (remarkBytes != null) {
            headerBuffer.putInt(remarkBytes.length);
            headerBuffer.put(remarkBytes);
        } else {
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小园子的小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值