1. NioServerSocketChannel:
1.1: 创建时机:
1.1.1: 在编码中指定了 channel(NioServerSocketChannel.class)
1.1.2 : 在bind 过程中执行 channelFactory.newChannel() 通过反射来创建NioServiceSocketChannel; (@see:io.netty.bootstrap.AbstractBootstrap#initAndRegister)
1.2: NioServerSocketChannel 组成部分:
1.2.1: Java Nio 中的ServerSocketChannel : 通过 SelectorProvider.provider().openServerSocketChannel() 创建;
1.2.2: readInterestOp 感兴趣的事件 :SelectionKey.OP_ACCEPT 即对连接事件感兴趣;
1.2.3: id 即ChannelId :NioServiceSocketChannel 对应的唯一ID;
1.2.4: unsafe:用来处理底层操作的对象;
1.2.5:pipeline:管道对象,服务端接收到请求的一个连续执行的逻辑对象;

2. pipeline(Netty 大动脉):
含义:pipeline Netty 大动脉,维护了netty 运行时 inbound 以及outbound 节点,并形成链表结构。
2.1:pipline创建时机:创建的时机是跟随者NioServerSocketChannel 一起创建的
2.2:pipline组成部分(以下三部分组成了head--myself--tail 双向链表结构):
2.2.1:TailContext :尾部哨兵上下文节点
2.2.2:HeadContext:头部哨兵上下文节点
2.2.3:我们自己定义的Handler:中间上下文节点
TailContext 类结构:

HeadContext 结构:

从HeadContext 和TailConext 结构分析:
HeadContext 实现了ChannelOutBoundHandler 以及ChannelInbountHandler接口;
TailContext 实现了ChannelInbountHandler 接口;
ChannelInbountHandler 主要用来负责处理事件的回调,状态的改变(比如监听到读的消息);
ChannelOutboundHandler 主要进行IO 方面的操作(比如 写的操作);
2. unsafe:
4. EventLoopGroup:
4.1:NioServerSocketChannel 组成部分:
4.1.1: 根据线程数来创建多少 个NioEventLoop 。
4.1.2: 创建 EventExecutorChooser 选择器,用于选择NioEventLoop,用来将事件平分到每一个EventLoop 上。
4.1.3: 创建 ThreadPerTaskExecutor 任务执行器,用来创建新的线程,并进行启动EventLoop。
4.2:类结构图:

5. NioEventLoop:
5.1:NioEventLoop 创建时机:
NioEventLoop 的创建是随着NioEventLoopGroup 的初始化而创建的 @see io.netty.channel.nio.NioEventLoopGroup#newChild
5.2:NioEventLoop 组成部分:
5.2.1: ThreadPerTaskExecutor 任务执行器,用于创建新的线程并执行;
5.2.2: SelectorProvider.provider() Java selector
5.2.3: DefaultSelectStrategyFactory
5.2.4: RejectedExecutionHandler
5.2.5: taskQueue即 newMpscQueue
5.3:NioEventLoop 运行时机以及过程:
5.3.1:在端口绑定注册的时候进行NioEventLoop 内部线程的创建(io.netty.channel.AbstractChannel.AbstractUnsafe#register)。
io.netty.util.concurrent.SingleThreadEventExecutor#execute
io.netty.util.concurrent.SingleThreadEventExecutor#startThread
io.netty.util.concurrent.SingleThreadEventExecutor#doStartThread(创建新线程并于eventLoop 绑定)
io.netty.util.concurrent.SingleThreadEventExecutor#run(for 循环处理io 事件)
@Override public final void register(EventLoop eventLoop, final ChannelPromise promise) { if (eventLoop == null) { throw new NullPointerException("eventLoop"); } if (isRegistered()) { promise.setFailure(new IllegalStateException("registered to an event loop already")); return; } if (!isCompatible(eventLoop)) { promise.setFailure( new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName())); return; } AbstractChannel.this.eventLoop = eventLoop; if (eventLoop.inEventLoop()) { register0(promise); } else { try { //入口,进行eventLoop 的启动 eventLoop.execute(new Runnable() { @Override public void run() { register0(promise); } }); } catch (Throwable t) { logger.warn( "Force-closing a channel whose registration task was not accepted by an event loop: {}", AbstractChannel.this, t); closeForcibly(); closeFuture.setClosed(); safeSetFailure(promise, t); } } }
5.3.2:在新连接接入(NioSocketChannel )的时候进行NioEventLoop 内部线程的创建。
try { childGroup.register(child).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { forceClose(child, future.cause()); } } });
6. 端口绑定:
6.1 端口绑定过程
6.1.实例化NioServerSocketChannel 对象的创建(newChannel());
6.2.初始化NioServerSocketChannel pipeline 中添加Inbound处理器,为NioSocketChannel 新连接做准备( init(channel) )
6.3.boss group chooser 选择器中选择一个NioEventLoop 作为NioServerSocketChannel 的eventloop
6.4.将服务端channel 注册到 eventloop 维护的selector 中,并不对任何事件感兴趣(config().group().register(channel);)
6.5.端口绑定,并且对 OP_ACCEPT 感兴趣
6.2 具体端口绑定代码过程:
6.2.1 先进行NioServerSocketChannel 的实例化 以及注册
--源码位置:io.netty.bootstrap.AbstractBootstrap#initAndRegister
final ChannelFuture initAndRegister() { Channel channel = null; try { //1.实例化反射创建NioServerSocketChannel channel = channelFactory.newChannel(); //2.初始化NioServerSocketChannel 主要是为客户端新连接做准备 init(channel); } catch (Throwable t) { if (channel != null) { // channel can be null if newChannel crashed (eg SocketException("too many open files")) channel.unsafe().closeForcibly(); // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t); } // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor return new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE).setFailure(t); } //3.在NioEventLoop 线程中将serversSocketChannel注册到selector 中,并不对任何事件感兴趣 ChannelFuture regFuture = config().group().register(channel); if (regFuture.cause() != null) { if (channel.isRegistered()) { channel.close(); } else { channel.unsafe().closeForcibly(); } } // If we are here and the promise is not failed, it's one of the following cases: // 1) If we attempted registration from the event loop, the registration has been completed at this point. // i.e. It's safe to attempt bind() or connect() now because the channel has been registered. // 2) If we attempted registration from the other thread, the registration request has been successfully // added to the event loop's task queue for later execution. // i.e. It's safe to attempt bind() or connect() now: // because bind() or connect() will be executed *after* the scheduled registration task is executed // because register(), bind(), and connect() are all bound to the same thread. return regFuture; }
1.channelFactory.newChannel():反射创建NioServerSocketChannel ,此时 NioServerSocketChannel的pipeline 结构为:

2.在init(channel)后,向pipeline 节点中添加预新连接接入节点, 此时 NioServerSocketChannel的pipeline 结构为(如下):

3.在 config().group().register(channel) 注册完之后,将预新连接接入节点进行handlerAdded 的操作,此时的 NioServerSocketChannel的pipeline 结构为(如下),开始为客户端新连接做准备:

6.2.2 注册的具体流程:
(1)获取NioEventLoopGroup 即boosGroup
config().group() //这返回的是我们的boss NioEventLoopGroup
@SuppressWarnings("deprecation")
public final EventLoopGroup group() {
return bootstrap.group();
}
(2) chooser 获取一个 NioEventLoop 来注册NioServerSocketChannel
@Override
public ChannelFuture register(Channel channel) {
return next().register(channel);
}
//事件选择器为我们分配一个NioEventLoop进行后续注册操作
@Override
public EventExecutor next() {
return chooser.next();
}
(3) unsafe 注册
//unsafe 操作注册
@Override
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
promise.channel().unsafe().register(this, promise);
return promise;
}
(4)将chooser 获取到的NioEventLoop 与NioServerSocketChannel 进行绑定,然后NioEventLoop 启动进行注册;
@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
if (eventLoop == null) {
throw new NullPointerException("eventLoop");
}
if (isRegistered()) {
promise.setFailure(new IllegalStateException("registered to an event loop already"));
return;
}
if (!isCompatible(eventLoop)) {
promise.setFailure(
new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
return;
}
//将NioEventLoop 与NioServerSocketChannel进行绑定
AbstractChannel.this.eventLoop = eventLoop;
//此时的NioEventLoop 还未执行,还没有进行线程的创建,,所以这里返回false
if (eventLoop.inEventLoop()) {
register0(promise);
} else {
try {
//启动NioEventLoop 执行这里,将注册操作放入NioEventLoop 维护的队列中,去执行
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
logger.warn(
"Force-closing a channel whose registration task was not accepted by an event loop: {}",
AbstractChannel.this, t);
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
}
(5) NioEventLoop 启动(事件轮循)并进行注册:
public void execute(Runnable task) { if (task == null) { throw new NullPointerException("task"); } boolean inEventLoop = inEventLoop(); //将需要执行的任务放到队列中 addTask(task); if (!inEventLoop) { //开启线程进行循环 startThread(); if (isShutdown() && removeTask(task)) { reject(); } } if (!addTaskWakesUp && wakesUpForTask(task)) { wakeup(inEventLoop); } }
(6) 创建一条新的线程去执行任务,并绑定到NioEventLoop上
private void doStartThread() { assert thread == null; //创建一条新的线程去执行任务 executor.execute(new Runnable() { @Override public void run() { //将创建的线程绑定在NioEventLoop上 thread = Thread.currentThread(); if (interrupted) { thread.interrupt(); } boolean success = false; updateLastExecutionTime(); try { //事件轮训,并且执行放入队列的任务 SingleThreadEventExecutor.this.run(); success = true; } catch (Throwable t) { logger.warn("Unexpected exception from an event executor: ", t); } finally { for (;;) { int oldState = state; if (oldState >= ST_SHUTTING_DOWN || STATE_UPDATER.compareAndSet( SingleThreadEventExecutor.this, oldState, ST_SHUTTING_DOWN)) { break; } } // Check if confirmShutdown() was called at the end of the loop. if (success && gracefulShutdownStartTime == 0) { logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " + SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called " + "before run() implementation terminates."); } try { // Run all remaining tasks and shutdown hooks. for (;;) { if (confirmShutdown()) { break; } } } finally { try { cleanup(); } finally { STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED); threadLock.release(); if (!taskQueue.isEmpty()) { logger.warn( "An event executor terminated with " + "non-empty task queue (" + taskQueue.size() + ')'); } terminationFuture.setSuccess(null); } } } } }); }
(7)Java 注册
private void register0(ChannelPromise promise) { try { // check if the channel is still open as it could be closed in the mean time when the register // call was outside of the eventLoop if (!promise.setUncancellable() || !ensureOpen(promise)) { return; } boolean firstRegistration = neverRegistered; //将ServerSocketChannel 注册到selector 中,并不对任何事件感兴趣 doRegister(); neverRegistered = false; registered = true; // Ensure we call handlerAdded(...) before we actually notify the promise. This is needed as the // user may already fire events through the pipeline in the ChannelFutureListener. //为NioSeerverSocketChannel pipeline 中添 ServerBootstrapAcceptor新连接接入handler pipeline.invokeHandlerAddedIfNeeded(); // promise 设置为成功状态,并触发成功后的监听回调(后续端口绑定依赖于此操作) safeSetSuccess(promise); pipeline.fireChannelRegistered(); // Only fire a channelActive if the channel has never been registered. This prevents firing // multiple channel actives if the channel is deregistered and re-registered. if (isActive()) { if (firstRegistration) { pipeline.fireChannelActive(); } else if (config().isAutoRead()) { // This channel was registered before and autoRead() is set. This means we need to begin read // again so that we process inbound data. // // See https://github.com/netty/netty/issues/4805 beginRead(); } } } catch (Throwable t) { // Close the channel directly to avoid FD leak. closeForcibly(); closeFuture.setClosed(); safeSetFailure(promise, t); } }
7. 新连接接入(客户端接入):
在 ServerSocketChannel 创建bind后,此时ServerSocketChannel pipeline 的结构如下,boos 线程就开始轮训开始监听客户端连接事件,得到新连接后,交给work 线程进行监听读写操作;

新连接触发时机:
work 线程 轮训连接事件:
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) { unsafe.read(); }
读取到客户端新连接:
int localRead = doReadMessages(readBuf); if (localRead == 0) { break; } if (localRead < 0) { closed = true; break; } allocHandle.incMessagesRead(localRead); } while (allocHandle.continueReading()); } catch (Throwable t) { exception = t; } int size = readBuf.size(); for (int i = 0; i < size; i ++) { readPending = false;
//传播channelread ,参数是niosocketchannel pipeline.fireChannelRead(readBuf.get(i)); } readBuf.clear(); allocHandle.readComplete(); pipeline.fireChannelReadComplete();
在新连接接入handle ServerBootstrapAcceptor 中处理channelread 操作,将 NioSocketChannel 注册到work 线程中,进行轮训:
public void channelRead(ChannelHandlerContext ctx, Object msg) { final Channel child = (Channel) msg; child.pipeline().addLast(childHandler); setChannelOptions(child, childOptions, logger); for (Entry<AttributeKey<?>, Object> e: childAttrs) { child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue()); } try {
//socketchannel 注册到work线程中 childGroup.register(child).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { forceClose(child, future.cause()); } } }); } catch (Throwable t) { forceClose(child, t); } }

浙公网安备 33010602011771号