由于工作的原因,需要在RocketMQ源码的基础上进行修改,实现自己的功能,因此打算读读源码,写写日记,后续会使用aeron替换掉netty,比较两者的性能指标。
RocketMQ主要包括NameSrv、Broker、Producer和Consumer四个模块,模块之间通过Netty进行底层网络传输,因此,RocketMQ的线程模型也是根据Netty的特点进行构建。
RocketMQ对Netty的封装
RocketMQ在原生Netty的基础上,封装了自己的Server和Client,分别为NettyRemotingServer和NettyRemotingClient,该部分的类关系如下图所示。其中NettyRemotingAbstract定义了消息在通过Netty接收并编解码为消息后的一系列业务操作;NettyRemotingServer和NettyRemotingClient是分别对Netty Server和Netty Client的接口封装。
以下的讲解需要首先了解一下Netty的基本使用方式,建议同学先去熟悉一下
Netty的客户端或者服务端在收到消息时,消息的数据流会流经在PipeLine上定义的所有ChannelHandler。以上文的NettyRemotingServer为例,以下代码创建了handshakeHandler、encoder、NettyDecoder、IdleStateHandler、connectionManageHandler和serverHandler总共六个ChannelHandler:
ServerBootstrap childHandler =
this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupSelector)
.channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.SO_KEEPALIVE, false)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSndBufSize())
.childOption(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketRcvBufSize())
.localAddress(new InetSocketAddress(this.nettyServerConfig.getListenPort()))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline()
.addLast(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, handshakeHandler)
.addLast(defaultEventExecutorGroup,
encoder,
new NettyDecoder(),
new IdleStateHandler(0, 0, nettyServerConfig.getServerChannelMaxIdleTimeSeconds()),
connectionManageHandler,
serverHandler
);