概述
在上一节 RocketMQ源码详解 | Producer篇 · 其二:消息组成、发送链路 中,我们终于将消息发送出了 Producer,在短暂的 tcp 握手后,很快它就会进入目的 Broker。这次我们来自底向上的看下 Broker 端是如何接收然后分发处理消息,同时了解 RocketMQ 的 Broker 的线程模型。
Netty 组件
如果你还记得上一节的内容的话那应该知道,NettyRomotingAbstract
有两个实现类,分别是 NettyRemotingClient
和 NettyRemotingServer
,我们已经知道了前者的实现,现在我们再来看看后者
NettyRemotingServer
这个类很长,我们先来看它的属性
/* 引导类和dispatch线程与select线程池 */ |
|
private final ServerBootstrap serverBootstrap; |
|
private final EventLoopGroup eventLoopGroupSelector; |
|
private final EventLoopGroup eventLoopGroupBoss; |
|
// 配置类 |
|
private final NettyServerConfig nettyServerConfig; |
|
// 用来执行 callback 函数的线程池 |
|
private final ExecutorService publicExecutor; |
|
// 自定义的 Channel 事件监听器 |
|
private final ChannelEventListener channelEventListener; |
|
// 扫描已经超时的 ResponseFeature |
|
private final Timer timer = new Timer("ServerHouseKeepingService", true); |
|
// 工作线程 |
|
private DefaultEventExecutorGroup defaultEventExecutorGroup; |
|
private int port = 0; |
|
private static final String HANDSHAKE_HANDLER_NAME = "handshakeHandler"; |
|
private static final String TLS_HANDLER_NAME = "sslHandler"; |
|
private static final String FILE_REGION_ENCODER_NAME = "fileRegionEncoder"; |
|
// sharable handlers |
|
private HandshakeHandler handshakeHandler; |
|
private NettyEncoder encoder; |
|
private NettyConnectManageHandler connectionManageHandler; |
|
private NettyServerHandler serverHandler; |
我们主要关心 serverBootStrap 的启动
首先是它的初始化,初始化代码较长,主要做了三件事:
- 初始化 callback 函数执行线程池
- 在 Linux 平台上启用 epoll
- 使用可能存在的 SSL
然后是重头戏,其具体的创建
ServerBootstrap childHandler = |
|
this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupSelector) |
|
.channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class) |
|
// 半连接队列长度 |
|
.option(ChannelOption.SO_BACKLOG, 1024) |
|
// 开启内核中的 net.ipv4.tcp_tw_reuse 选项 |
|
.option(ChannelOption.SO_REUSEADDR, true) |
|
// 关闭操作系统的连接维护,由自己去干 |
|
.option(ChannelOption.SO_KEEPALIVE, false) |
|
// 禁用 Nagle 算法 |
|
.childOption(ChannelOption.TCP_NODELAY, true) |
|
// 设定发送缓冲区和接收缓冲区大小 |
|
.childOption(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSndBufSize()) |
|
.childOption(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketRcvBufSize()) |