Kafka 网络模型

Kafka 的网络层没有用 Netty 作为底层的通信库,而是直接采用 Java NIO 实现网络通信。在网络模型中,也是参照 Reactor 多线程模型,采用多线程、多 Selector 的设计。

Processor 线程和 Handler 线程之间通过 RequestChannel 传递数据,RequestChannel 中包含一个 RequestQueue 队列和多个 ResponseQueues 队列。每个 Processor 线程对应一个 ResponseQueue。

image-20230717213627999

具体流程上:

  • 一个 Acceptor 接收客户端建立连接的请求,创建 Socket 连接并分配给 Processor 处理。

  • Processor 线程把读取到的请求存入 RequestQueue 中,Handler 线程从 RequestQueue 队列中取出请求进行处理。

  • Handler 线程处理请求产生的响应,会存放到 Processor 对应的 ResponseQueue 中,Processor 线程从其对应的 ResponseQueue 中取出响应信息,并返回给客户端。

RocketMQ 网络模型

RocketMQ 采用 Netty 组件作为底层通信库,遵循 Reactor 多线程模型,同时又在 Reactor 模型上做了一些扩展和优化。

所以它的网络模型是 Netty 的网络模型,Netty 底层采用的是主从 Reactor 多线程模型,模型的原理逻辑跟前面讲到的主从 Reactor 多线程模型是一样的。

image-20230717213829623

具体流程上:

  • 一个 Reactor 主线程负责监听 TCP 网络连接请求,建立好连接,创建 SocketChannel,并注册到 Selector 上。RocketMQ 的源码中会自动根据 OS 的类型选择 NIO 和 Epoll,也可以通过参数配置,监听真正的网络数据。

  • 接收到网络数据后,会把数据传递给 Reactor 线程池处理。

  • 真正执行业务逻辑之前,会进行 SSL 验证、编解码、空闲检查、网络连接管理,这些工作在 Worker 线程池处理(defaultEventExecutorGroup)。

  • 处理业务操作,放在业务 Processor 线程池中执行。

NIO 编程和 RPC 框架

因为 RPC 调用的是一个远端对象,调用者和被调用者处于不同的节点上,想完成调用,必须实现 4 个能力。

  • 网络传输协议:远端调用底层需要经过网络传输,所以需要选择网络通信协议,比如 TCP。

  • 应用通信协议:网络传输需要设计好应用层的通信协议,比如 HTTP2 或自定义协议。

  • 服务发现:调用的是远端对象,需要可以定位到调用的服务器地址以及调用的具体方法。

  • 序列化和反序列化:网络传输的是二进制数据,因此 RPC 框架需要自带序列化和反序列化的能力。

参考

《深入拆解消息队列 47 讲》