RocketMQ作为一个高效的分布式消息队列,通信质量是必须保证的,而Netty是一个高效的网络应用框架,因此RocketMQ选择Netty来实现底层的通信功能。
-
Netty介绍
Netty是一个高效的JAVA网络应用框架,它提供异步事件驱动的方式,使用Netty可以快速开发出高性能的网络应用程序。
Netty从很多协议实现中吸取了丰富的经验,比如SMTP、HTTP等基于二进制和文本的传统协议。借助Netty可以开发出高质量的通信程序。 -
Netty模型
如图所示,Netty主要分成三大部分:第一部分包括零拷贝技术、统一的通讯API和可扩展的事件模型;第 二部分是传输层;第三部分就是协议支持。
-
ByteBuffer的重新设计
CPU的处理速度比网络传输数据的速度要快得多,因此会引入缓冲区,让网络传输的数据先积压在缓冲区,等到有一定数量后再交给CPU做处理。Netty并没有使用原生的ByteBuffer,原生的ByteBuffer使用起来会复杂一些,像复位flip这样的操作都必须手动完成,Netty使用了自己重新实现的buffer API,功能上还包括允许自定义缓存类型,透明的零拷贝实现等等,使用上也更简单,更适合开发。
ByteBuffer实现的是一个轻量级的字节数组包装器,它有读写操作,相应的维护readerIndex和writerIndex,有了这两个索引可以很清晰的计算出可读部分(writerIndex - readerIndex)、可写部分(capacity - writerIndex)、废弃部分(readerIndex)。用户也能使用discardReadBytes主动清理掉废弃部分,增加更多的可写空间。和原生的ByteBuffer相比,Netty封装的ByteBuffer更简单、扩展性更大。 -
统一的I/O接口和拦截链的事件模型
Netty 提供了统一的异步I/O编程接口Channel,它抽象了所有点对点的操作。
public interface Channel extends AttributeMap, Comparable<Channel> {
EventLoop eventLoop();
Channel parent();
ChannelConfig config();
boolean isOpen();
boolean isRegistered();
Channel read();
ChannelFuture write(Object var1);
ChannelFuture write(Object var1, ChannelPromise var2);
Channel flush();
ChannelFuture writeAndFlush(Object var1, ChannelPromise var2);
ChannelFuture writeAndFlush(Object var1);
...
}
那我们再谈基于拦截链的事件模型。Netty具有良好的I/O事件模型,整体的层次结构是严格定义的,允许在不破坏现有代码的结构上自定义事件类型,扩散性很好。在Netty中,ChannelPipeline在初始化时可以定义一系列的Handler,那么ChannelPipeline 内部的channelEvent就会被这一组Handler处理,也就是说对于事件的处理过程以及管道内部处理器的交互过程,用户会具有绝对的控制力。
-
RocketMQ基于Netty的通信实现
RemotingServer、RemotingClient分别对应通信的服务端和客户端。下面将介绍RemotingServer这个顶层通信类,RemotingClient过程类似。
- RemotingServer
public interface RemotingService {
void start();// 客户端服务端都需要启动程序,下面同理
void shutdown();
void registerRPCHook(RPCHook rpcHook);
}
public interface RemotingServer extends RemotingService {
void registerProcessor(final int requestCode, final NettyRequestProcessor processor,
final ExecutorService executor);
// 设置接收到消息后的处理方法
void registerDefaultProcessor(final NettyRequestProcessor processor, final ExecutorService executor);
int localListenPort();
Pair<NettyRequestProcessor, ExecutorService> getProcessorPair(final int requestCode);
RemotingCommand invokeSync(final Channel channel, final RemotingCommand request,
final long timeoutMillis) throws InterruptedException, RemotingSendRequestException,
RemotingTimeoutException;
void invokeAsync(final Channel channel, final RemotingCommand request, final long timeoutMillis,
final InvokeCallback invokeCallback) throws InterruptedException,
RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException;
void invokeOneway(final Channel channel, final RemotingCommand request, final long timeoutMillis)
throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException,
RemotingSendRequestException;
}
NettyRemotingServer是RemotingServer的一个实现,下面将详细分析NettyRemotingServer类。
public NettyRemotingServer(final NettyServerConfig nettyServerConfig) {
this(nettyServerConfig, null);
}
public NettyRemotingServer(final NettyServerConfig nettyServerConfig,
final ChannelEventListener channelEventListener) {
super