通道
1.1 Socket描述符
理论上来说,操作系统底层的socket描述符分为两类:
- 连接监听类型。连接监听类型的socket描述符,放在服务器端,它负责接收客户端的套接字连接;在服务器端,一个“连接监听类型”的socket描述符可以接受(Accept)成千上万的传输类的socket描述符。
- 传输数据类型。数据传输类的socket描述符负责传输数据。同一条TCP的Socket传输链路,在服务器和客户端,都分别会有一个与之相对应的数据传输类型的socket描述符。
1.2 父子通道
在Netty中,每一个NioSocketChannel通道所封装的是Java NIO通道,再往下就对应到了操作系统底层的socket描述符。
NioServerSocketChannel负责服务器连接监听和接收,也叫父通道(Parent Channel)。
对应于每一个接收到的NioSocketChannel传输类通道,也叫子通道(Child Channel)
父通道接受请求会创建一个子通道,对应socket 请求接受之后,fork()新建一个socket连接。
1.3 AbstractChannel
AbstractChannel内部有一个parent属性,表示通道的父通道。对于连接监听通道(如NioServerSocketChannel实例)来说,其父亲通道为null;而对于每一条传输通道(如NioSocketChannel实例),其parent属性的值为接收到该连接的服务器连接监听通道。
反应器
NioEventLoop
是一个单线程的反应器。
public final class NioEventLoop extends SingleThreadEventLoop {
/**
*The NIO {@link Selector}.
*/
//通过select方法,选择器可以不断地选择通道中所发生操作的状态,返回注册过的感兴趣的那些IO事件
private Selector selector;//通道和选择器绑定之后就能获取感兴趣的事件了
private Selector unwrappedSelector;
private SelectedSelectionKeySet selectedKeys;
EventLoopGroup线程组
Netty的程序开发不会直接使用单个EventLoop线程,而是使用EventLoopGroup线程组。
Netty的EventLoopGroup线程组是一个多线程版本的反应器(Reactor),多个EventLoop线程组成一个EventLoopGroup线程组。
结构
EventLoopGroup构造方法可以使用默认的,也可以指定线程数
/** * Create a new instance using the default number of threads,
the default {@link ThreadFactory} and * the {@link SelectorProvider} which is returned by {@link
SelectorProvider#provider()}. */public NioEventLoopGroup() { this(0);}/** * Create a new instance using the specified number of
threads, {@link ThreadFactory} and the * {@link SelectorProvider} which is returned by {@link
SelectorProvider#provider()}. */public NioEventLoopGroup(int nThreads) { this(nThreads, (Executor) null);}
默认的构造方法线程数,是cpu核心的2倍数
static {
DEFAULT_EVENT_LOOP_THREADS = Math.max(1,
SystemPropertyUtil.getInt("io.netty.eventLoopThreads",
NettyRuntime.availableProcessors() * 2));
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.eventLoopThreads: {}",
DEFAULT_EVENT_LOOP_THREADS);
}
}
负责新连接的监听和接受的EventLoopGroup线程组,查询父通道(NioServerSocketChannel
)的IO事件,是否有新的连接请求过来。另一个EventLoopGroup线程组负责查询所有子通道(NioSocketChannel
)的IO事件,并且执行Handler处理器中的业务处理——例如数据的输入和输出。