NettyUtils 用于基于NIO或EPOLL创建Netty概念
Utilities for creating various Netty constructs based on whether we’re using EPOLL or NIO.
1.1、getClientChannelClass
根据IOMode,获取对应的SocketChannel
/**
* Returns the correct (client) SocketChannel class based on IOMode.
*/
public static Class<? extends Channel> getClientChannelClass(IOMode mode) {
switch (mode) {
case NIO:
return NioSocketChannel.class;
case EPOLL:
return EpollSocketChannel.class;
default:
throw new IllegalArgumentException("Unknown io mode: " + mode);
}
}
1.2、createEventLoop
根据IOMode,创建Netty的EventLoopGroup。
/**
* Creates a Netty EventLoopGroup based on the IOMode.
*/
public static EventLoopGroup createEventLoop(IOMode mode, int numThreads, String threadPrefix) {
ThreadFactory threadFactory = createThreadFactory(threadPrefix);
switch (mode) {
case NIO:
return new NioEventLoopGroup(numThreads, threadFactory);
case EPOLL:
return new EpollEventLoopGroup(numThreads, threadFactory);
default:
throw new IllegalArgumentException("Unknown io mode: " + mode);
}
}
1.3、createPooledByteBufAllocator
创建一个汇集ByteBuf但对本地线程缓存禁用的分配器。为什么要对本地线程缓存禁用?因为ByteBuf都是由事件循环线程分配,所以线程本地缓存对于TransportClient是禁用的。但是ByteBuf的释放却是由Executor线程,而不是事件循环线程来完成。本地线程缓存经常会延迟ByteBuf的回收,导致巨大的内存消耗。
/**
* Create a pooled ByteBuf allocator but disables the thread-local cache. Thread-local caches
* are disabled for TransportClients because the ByteBufs are allocated by the event loop thread,
* but released by the executor thread rather than the event loop thread. Those thread-local
* caches actually delay the recycling of buffers, leading to larger memory usage.
*/
public static PooledByteBufAllocator createPooledByteBufAllocator(
boolean allowDirectBufs,
boolean allowCache,
int numCores) {
if (numCores == 0) {
numCores = Runtime.getRuntime().availableProcessors();
}
return new PooledByteBufAllocator(
allowDirectBufs && PlatformDependent.directBufferPreferred(),
Math.min(getPrivateStaticField("DEFAULT_NUM_HEAP_ARENA"), numCores),
Math.min(getPrivateStaticField("DEFAULT_NUM_DIRECT_ARENA"), allowDirectBufs ? numCores : 0),
getPrivateStaticField("DEFAULT_PAGE_SIZE"),
getPrivateStaticField("DEFAULT_MAX_ORDER"),
allowCache ? getPrivateStaticField("DEFAULT_TINY_CACHE_SIZE") : 0,
allowCache ? getPrivateStaticField("DEFAULT_SMALL_CACHE_SIZE") : 0,
allowCache ? getPrivateStaticField("DEFAULT_NORMAL_CACHE_SIZE") : 0
);
}
1.4、createFrameDecoder
对从管道中读取的ByteBuf按照数据帧进行解析;
/**
* Creates a LengthFieldBasedFrameDecoder where the first 8 bytes are the length of the frame.
* This is used before all decoders.
*/
public static TransportFrameDecoder createFrameDecoder() {
return new TransportFrameDecoder();
}