一、NioEventLoopGroup和NioEventLoop的UML类图
二、NioEventLoopGroup初始化流程
- 从new一个NioEventLoopGroup开始
//一、NioEventLoopGroup的构造器 //1.传入线程数 public NioEventLoopGroup(int nThreads) { //新增传入为null的执行器 this(nThreads, (Executor) null); } //2.构造器 public NioEventLoopGroup(int nThreads, Executor executor) { //新增传入java底层的selector提供器 this(nThreads, executor, SelectorProvider.provider()); } //3.构造器 public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider) { //新增传入默认选择器策略工厂 this(nThreads, executor, selectorProvider, DefaultSelectStrategyFactory.INSTANCE); } //4.构造器 public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider, final SelectStrategyFactory selectStrategyFactory) { //新增传入执行器拒绝策略 super(nThreads, executor, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject()); } //二、NioEventLoopGroup的父类MultithreadEventLoopGroup的构造器 //1.将selector提供器、选择器策略工厂和执行器拒绝策略 包装成可变参数 protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) { /** DEFAULT_EVENT_LOOP_THREADS 默认线程数在类加载的时候初始化静态代码块设置为CPU核心数*2 private static final int DEFAULT_EVENT_LOOP_THREADS; 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); } } **/ super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args); } //三、MultithreadEventLoopGroup的父类MultithreadEventExecutorGroup的构造器 //1.构造器 protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) { //新增传入 事件执行选择器(新的连接进来,选择不同的NioEventLoop) this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args); } //2.构造器 protected MultithreadEventExecutorGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory, Object... args) { if (nThreads <= 0) { throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads)); } if (executor == null) { //newDefaultThreadFactory()创建能定义线程名的线程工厂, 它有个newThread方法可以创建FastThreadLocalThread //并创建ThreadPerTaskExecutor执行器(被执行的runnable线程会用FastThreadLocalRunnable包装优化,具体https://www.jianshu.com/p/3fc2fbac4bb7) executor = new ThreadPerTaskExecutor(newDefaultThreadFactory()); } //初始化NioEventLoop线程池组 children = new EventExecutor[nThreads]; //循环 for (int i = 0; i < nThreads; i ++) { boolean success = false; try { //创建NioEventLoop 详见 三、NioEventLoop的初始化 children[i] = newChild(executor, args); success = true; } catch (Exception e) { // TODO: Think about if this is a good exception type throw new IllegalStateException("failed to create a child event loop", e); } finally { if (!success) { for (int j = 0; j < i; j ++) { children[j].shutdownGracefully(); } for (int j = 0; j < i; j ++) { EventExecutor e = children[j]; try { while (!e.isTerminated()) { e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); } } catch (InterruptedException interrupted) { // Let the caller handle the interruption. Thread.currentThread().interrupt(); break; } } } } } //初始化NioEventLoop选择器,连接进来选择哪个NioEventLoop, //Netty根据你传入的的线程数做了细节优化,计算机底层&运算比%运算效率高27倍,所以线程数是2的倍数用的是位运算 chooser = chooserFactory.newChooser(children); final FutureListener<Object> terminationListener = new FutureListener<Object>() { @Override public void operationComplete(Future<Object> future) throws Exception { if (terminatedChildren.incrementAndGet() == children.length) { terminationFuture.setSuccess(null); } } }; for (EventExecutor e: children) { e.terminationFuture().addListener(terminationListener); } Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length); Collections.addAll(childrenSet, children); readonlyChildren = Collections.unmodifiableSet(childrenSet); }
三、NioEventLoop初始化
- 从NioEventLoopGroup的 children[i] = newChild(executor, args);开始
//1. 创建NioEventLoop //传入执行器, args= selector提供器、selector策略工厂、执行器拒绝策略 @Override protected EventLoop newChild(Executor executor, Object... args) throws Exception { //this=NioEventLoopGroup return new NioEventLoop(this, executor, (SelectorProvider) args[0], ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]); } //2. NioEventLoop构造器 NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) { super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler); if (selectorProvider == null) { throw new NullPointerException("selectorProvider"); } if (strategy == null) { throw new NullPointerException("selectStrategy"); } provider = selectorProvider; final SelectorTuple selectorTuple = openSelector(); selector = selectorTuple.selector; unwrappedSelector = selectorTuple.unwrappedSelector; selectStrategy = strategy; } //3. NioEventLoop父类SingleThreadEventLoop构造器 protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, boolean addTaskWakesUp, int maxPendingTasks, RejectedExecutionHandler rejectedExecutionHandler) { super(parent, executor, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler); //赋值,创建适合nio的多生产者单消费者的无锁尾部队列(这个Mpsc队列支持并发插入,插入时好像是while循环CAS操作,保证next节点始终是下一个元素) tailTasks = newTaskQueue(maxPendingTasks); } //4. SingleThreadEventLoop父类SingleThreadEventExecutor构造器 protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor, boolean addTaskWakesUp, int maxPendingTasks, RejectedExecutionHandler rejectedHandler) { super(parent); //赋值,任务队列初始唤醒状态为false this.addTaskWakesUp = addTaskWakesUp; //赋值,最大等待任务Integer的MAX this.maxPendingTasks = Math.max(16, maxPendingTasks); //赋值,执行器 this.executor = ObjectUtil.checkNotNull(executor, "executor"); //赋值,任务队列(同tailTasks尾部队列) taskQueue = newTaskQueue(this.maxPendingTasks); //赋值,执行器拒绝策略 rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler"); } //5. SingleThreadEventExecutor父类AbstractScheduledEventExecutor构造器 protected AbstractScheduledEventExecutor(EventExecutorGroup parent) { super(parent); } //6. AbstractScheduledEventExecutor父类AbstractEventExecutor构造器 protected AbstractEventExecutor(EventExecutorGroup parent) { //赋值,将NioEventLoopGroup保存起来 this.parent = parent; } //7. 再次回到第二步的 final SelectorTuple selectorTuple = openSelector(); private SelectorTuple openSelector() { final Selector unwrappedSelector; try { //jdk提供的多路复用器selector unwrappedSelector = provider.openSelector(); } catch (IOException e) { throw new ChannelException("failed to open a new selector", e); } //是否开启jdk的SelectionKeys的优化,默认false表示开启了 if (DISABLE_KEYSET_OPTIMIZATION) { return new SelectorTuple(unwrappedSelector); } //new一个SelectedSelectionKeySet 替换jdk的SelectionKeys final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet(); //反射获取jdk的"sun.nio.ch.SelectorImpl" Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { try { return Class.forName( "sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader()); } catch (Throwable cause) { return cause; } } }); if (!(maybeSelectorImplClass instanceof Class) || // ensure the current selector implementation is what we can instrument. !((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) { if (maybeSelectorImplClass instanceof Throwable) { Throwable t = (Throwable) maybeSelectorImplClass; logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, t); } return new SelectorTuple(unwrappedSelector); } final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass; Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { try { //获取selectedKeys属性字段 Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys"); //获取publicSelectedKeys属性字段 Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys"); //反射强吻获取权限 Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true); if (cause != null) { return cause; } //反射强吻获取权限 cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true); if (cause != null) { return cause; } //原生的selector的属性Set<SelectionKey> selectedKeys = new HashSet();集合替换成SelectedSelectionKeySet对象 selectedKeysField.set(unwrappedSelector, selectedKeySet); //原生的selector的属性Set<SelectionKey> publicKeys;集合替换成SelectedSelectionKeySet对象 publicSelectedKeysField.set(unwrappedSelector, selectedKeySet); return null; } catch (NoSuchFieldException e) { return e; } catch (IllegalAccessException e) { return e; } } }); if (maybeException instanceof Exception) { selectedKeys = null; Exception e = (Exception) maybeException; logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, e); return new SelectorTuple(unwrappedSelector); } selectedKeys = selectedKeySet; logger.trace("instrumented a special java.util.Set into: {}", unwrappedSelector); //最终将Selector原生HashSet结构替换成数组结构,因为HashSet底层是HashMap,add元素时候时间复杂度是O(n),而数组则是O(1) return new SelectorTuple(unwrappedSelector, new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet)); }
四、Netty如何工作
- 从ServerBootstrap的bind方法开始:
initAndRegister();方法
//1. 绑定端口 public ChannelFuture bind(SocketAddress localAddress) { validate(); if (localAddress == null) { throw new NullPointerException("localAddress"); } return doBind(localAddress); } //2. 调用doBind方法 private ChannelFuture doBind(final SocketAddress localAddress) { final ChannelFuture regFuture = initAndRegister(); final Channel channel = regFuture.channel(); if (regFuture.cause() != null) { return regFuture; } if (regFuture.isDone()) { // At this point we know that the registration was complete and successful. ChannelPromise promise = channel.newPromise(); doBind0(regFuture, channel, localAddress, promise); return promise; } else { // Registration future is almost always fulfilled already, but just in case it's not. final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel); regFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { Throwable cause = future.cause(); if (cause != null) { // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an // IllegalStateException once we try to access the EventLoop of the Channel. promise.setFailure(cause); } else { // Registration was successful, so set the correct executor to use. // See https://github.com/netty/netty/issues/2586 promise.registered(); doBind0(regFuture, channel, localAddress, promise); } } }); return promise; } } //3. 调用doBind → initAndRegister方法 final ChannelFuture initAndRegister() { Channel channel = null; try { /** 反射获取NioServerSocketChannel(它class是我们传入的) **/ channel = channelFactory.newChannel(); 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); } 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; } //4. 调用 doBind → initAndRegister → newChannel方法 public T newChannel() { try { return clazz.getConstructor().newInstance(); } catch (Throwable t) { throw new ChannelException("Unable to create Channel from class " + clazz, t); } } //5. 调用 doBind → initAndRegister → init方法 @Override void init(Channel channel) throws Exception { //ServerBootstrap创建时如果设置了NioServerSokectChannel的选项,就把它设置进去 final Map<ChannelOption<?>, Object> options = options0(); //LinkedHashMap线程不安全 synchronized (options) { setChannelOptions(channel, options, logger); } //ServerBootstrap创建时如果设置了NioServerSokectChannel的属性,就把它设置进去 final Map<AttributeKey<?>, Object> attrs = attrs0(); //LinkedHashMap线程不安全 synchronized (attrs) { for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) { @SuppressWarnings("unchecked") AttributeKey<Object> key = (AttributeKey<Object>) e.getKey(); channel.attr(key).set(e.getValue()); } } //拿到pipeline ChannelPipeline p = channel.pipeline(); final EventLoopGroup currentChildGroup = childGroup; final ChannelHandler currentChildHandler = childHandler; final Entry<ChannelOption<?>, Object>[] currentChildOptions; final Entry<AttributeKey<?>, Object>[] currentChildAttrs; //设置客户端连接的选项 synchronized (childOptions) { currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size())); } //设置客户端连接的属性 synchronized (childAttrs) { currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size())); } p.addLast(new ChannelInitializer<Channel>() { @Override public void initChannel(final Channel ch) throws Exception { final ChannelPipeline pipeline = ch.pipeline(); ChannelHandler handler = config.handler(); if (handler != null) { pipeline.addLast(handler); } ch.eventLoop().execute(new Runnable() { @Override public void run() { pipeline.addLast(new ServerBootstrapAcceptor( ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)); } }); } }); } //6. 调用 doBind → initAndRegister → init → p.addLast方法 //6 -(1) @Override public final ChannelPipeline addLast(ChannelHandler... handlers) { //6 -(2) return addLast(null, handlers); } //6 -(2) @Override public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) { if (handlers == null) { throw new NullPointerException("handlers"); } for (ChannelHandler h: handlers) { if (h == null) { break; } //6 -(3) addLast(executor, null, h); } return this; } //6 -(3) @Override public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) { final AbstractChannelHandlerContext newCtx; synchronized (this) { //检查是否有@Sharable注解(作用:ChannelHandler是否可以在多个channel直接共享)或者 有没有被使用过,没有注解且被使用则抛异常 checkMultiplicity(handler); //ChannelHandler封装成ChannelHandlerContext (ChannelHandlerContext 是连接ChannelPipeline和ChannelHandler的桥梁) newCtx = newContext(group, filterName(name, handler), handler); //6 -(4) addLast0(newCtx); // If the registered is false it means that the channel was not registered on an eventloop yet. // In this case we add the context to the pipeline and add a task that will call // ChannelHandler.handlerAdded(...) once the channel is registered. //进入这里 并把ChannelHandlerContext包装成一个任务 if (!registered) { newCtx.setAddPending(); callHandlerCallbackLater(newCtx, true); return this; } EventExecutor executor = newCtx.executor(); if (!executor.inEventLoop()) { newCtx.setAddPending(); executor.execute(new Runnable() { @Override public void run() { callHandlerAdded0(newCtx); } }); return this; } } callHandlerAdded0(newCtx); return this; } //6 -(4) private void addLast0(AbstractChannelHandlerContext newCtx) { AbstractChannelHandlerContext prev = tail.prev; newCtx.prev = prev; newCtx.next = tail; prev.next = newCtx; tail.prev = newCtx; } //7. 分析重写的initChannel方法 p.addLast(new ChannelInitializer<Channel>() { @Override public void initChannel(final Channel ch) throws Exception { final ChannelPipeline pipeline = ch.pipeline(); //ServerBootstrap创建时如果设置了NioServerSokectChannel的ChannelHandler ,就把它添加进pipeline中 ChannelHandler handler = config.handler(); if (handler != null) { //可以debug看看,这个handler的handlerAdded方法会被回调~~ pipeline.addLast(handler); } //这里很重要,用channel绑定的NioEventLoop执行一个任务,把Acceptor派发器添加进NioServerSokectChannel的pipeline中,用于给每个连进来的NioSocketChannel初始化 //它传入NioServerSocketChannel、worker线程组、所有的连接ChannelHandler、选项配置、属性配置 ch.eventLoop().execute(new Runnable() { @Override public void run() { //7 -(1) pipeline.addLast(new ServerBootstrapAcceptor( ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)); } }); //7 -(1) ServerBootstrapAcceptor的channelRead方法 @Override @SuppressWarnings("unchecked") public void channelRead(ChannelHandlerContext ctx, Object msg) { //拿到NioSocketChannel final Channel child = (Channel) msg; //将NioSocketChannel的pipeline初始化 child.pipeline().addLast(childHandler); //将NioSocketChannel的选项初始化 setChannelOptions(child, childOptions, logger); //将NioSocketChannel的属性初始化 for (Entry<AttributeKey<?>, Object> e: childAttrs) { child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue()); } try { //从worker线程组中抽一个NioEventLoop,并将NioSocketChannel注册到NioEventLoop上和添加监听器 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); } } //8. 回到//3. 步 final ChannelFuture initAndRegister() { Channel channel = null; try { channel = channelFactory.newChannel(); 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); } //boss线程组注册NioServerSocketChannel //8 -(1) 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; } //8 -(1) @Override public ChannelFuture register(Channel channel) { //chooser选择器获取一个NioEventLoop并register //8 -(2) return next().register(channel); } //8 -(2) @Override public ChannelFuture register(Channel channel) { //1.创建DefaultChannelPromise,构造器传入NioServerSocketChannel 和 NioEventLoop //2.register //8 -(3) return register(new DefaultChannelPromise(channel, this)); } //8 -(3) @Override public ChannelFuture register(final ChannelPromise promise) { ObjectUtil.checkNotNull(promise, "promise"); //1.拿到NioMessageUnsafe //2.NioMessageUnsafe父类AbstractUnsafe中进行register //8 -(4) promise.channel().unsafe().register(this, promise); return promise; } //8 -(4) AbstractUnsafe类 @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; } //给NioServerSocketChannel保存NioEnvetLoop AbstractChannel.this.eventLoop = eventLoop; //netty的线程模型高性能在于对当前线程身份的确认 //eventLoop当前不在自己的线程中 if (eventLoop.inEventLoop()) { register0(promise); //这里eventLoop把boss线程启动了,把这个runnable加入任务队列,并启动boss线程执行 } else { try { eventLoop.execute(new Runnable() { @Override public void run() { //8 -(5) 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); } } } //8 -(5) 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; //进行注册 //8 -(6) 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. //如果pipeline中有需要执行的HandlerAdded就去执行 //8 -(7) pipeline.invokeHandlerAddedIfNeeded(); //这步告诉ChannelPromise设置成功了 //这将影响到第 //2 步中 regFuture.isDone()的判断结果 safeSetSuccess(promise); //8 -(12) 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); } } //8 -(6) @Override protected void doRegister() throws Exception { boolean selected = false; for (;;) { try { //1.jdk的注册,将ServerSocketChannel注册到Selector上,感兴趣事件是0,并把NioServerSocketChannel绑定selectKey 上 //2.有异常就强制刷新一次 //3.还是注册失败就抛异常 selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this); return; } catch (CancelledKeyException e) { if (!selected) { // Force the Selector to select now as the "canceled" SelectionKey may still be // cached and not removed because no Select.select(..) operation was called yet. eventLoop().selectNow(); selected = true; } else { // We forced a select operation on the selector before but the SelectionKey is still cached // for whatever reason. JDK bug ? throw e; } } } } //8 -(7) final void invokeHandlerAddedIfNeeded() { //很明显是在boss线程 assert channel.eventLoop().inEventLoop(); if (firstRegistration) { firstRegistration = false; // We are now registered to the EventLoop. It's time to call the callbacks for the ChannelHandlers, // that were added before the registration was done. //处理之前在//6 -(3)中被包装成任务的ChannelHandlerContext //8 -(8) callHandlerAddedForAllHandlers(); } } //8 -(8) private void callHandlerAddedForAllHandlers() { final PendingHandlerCallback pendingHandlerCallbackHead; synchronized (this) { assert !registered; // This Channel itself was registered. registered = true; pendingHandlerCallbackHead = this.pendingHandlerCallbackHead; // Null out so it can be GC'ed. this.pendingHandlerCallbackHead = null; } // This must happen outside of the synchronized(...) block as otherwise handlerAdded(...) may be called while // holding the lock and so produce a deadlock if handlerAdded(...) will try to add another handler from outside // the EventLoop. PendingHandlerCallback task = pendingHandlerCallbackHead; while (task != null) {. //PendingHandlerAddedTask //8 -(8) task.execute(); task = task.next; } } //8 -(8) @Override void execute() { EventExecutor executor = ctx.executor(); //明显是在当前的NioEventLoop线程中 if (executor.inEventLoop()) { //8 -(9) callHandlerAdded0(ctx); } else { try { executor.execute(this); } catch (RejectedExecutionException e) { if (logger.isWarnEnabled()) { logger.warn( "Can't invoke handlerAdded() as the EventExecutor {} rejected it, removing handler {}.", executor, ctx.name(), e); } remove0(ctx); ctx.setRemoved(); } } } //8 -(9) private void callHandlerAdded0(final AbstractChannelHandlerContext ctx) { try { // We must call setAddComplete before calling handlerAdded. Otherwise if the handlerAdded method generates // any pipeline events ctx.handler() will miss them because the state will not allow it. ctx.setAddComplete(); //回调ChannelHandler的handlerAdded方法 //8 -(10) ctx.handler().handlerAdded(ctx); } catch (Throwable t) { boolean removed = false; try { remove0(ctx); try { ctx.handler().handlerRemoved(ctx); } finally { ctx.setRemoved(); } removed = true; } catch (Throwable t2) { if (logger.isWarnEnabled()) { logger.warn("Failed to remove a handler: " + ctx.name(), t2); } } if (removed) { fireExceptionCaught(new ChannelPipelineException( ctx.handler().getClass().getName() + ".handlerAdded() has thrown an exception; removed.", t)); } else { fireExceptionCaught(new ChannelPipelineException( ctx.handler().getClass().getName() + ".handlerAdded() has thrown an exception; also failed to remove.", t)); } } } //8 -(10) 当前是被回调的是 ChannelInitializer类 /** * {@inheritDoc} If override this method ensure you call super! */ @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { if (ctx.channel().isRegistered()) { // This should always be true with our current DefaultChannelPipeline implementation. // The good thing about calling initChannel(...) in handlerAdded(...) is that there will be no ordering // surprises if a ChannelInitializer will add another ChannelInitializer. This is as all handlers // will be added in the expected order. //8 -(11) initChannel(ctx); } } //8 -(11) 看完跳回 //8 -(5) 步 还是ChannelInitializer的方法 private boolean initChannel(ChannelHandlerContext ctx) throws Exception { if (initMap.putIfAbsent(ctx, Boolean.TRUE) == null) { // Guard against re-entrance. try { //这个就回到我们 //5 步中重写的initChannel方法 initChannel((C) ctx.channel()); } catch (Throwable cause) { // Explicitly call exceptionCaught(...) as we removed the handler before calling initChannel(...). // We do so to prevent multiple calls to initChannel(...). exceptionCaught(ctx, cause); } finally { remove(ctx); } return true; } return false; } //8 -(12) @Override public final ChannelPipeline fireChannelRegistered() { //从pipeline的头结点的下一个结点开始 //8 -(13) AbstractChannelHandlerContext.invokeChannelRegistered(head); return this; } //8 -(13) static void invokeChannelRegistered(final AbstractChannelHandlerContext next) { EventExecutor executor = next.executor(); if (executor.inEventLoop()) { //8 -(14) next.invokeChannelRegistered(); } else { executor.execute(new Runnable() { @Override public void run() { next.invokeChannelRegistered(); } }); } } //8 -(14) private void invokeChannelRegistered() { if (invokeHandler()) { try { //调用pipeline上所有的ChannelHandler的channelRegistered方法 //8 -(15) 当前调用的是HeadContext ((ChannelInboundHandler) handler()).channelRegistered(this); } catch (Throwable t) { notifyHandlerException(t); } } else { fireChannelRegistered(); } } //8 -(15) @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { //head结点中再次检查pipeline是否有延迟执行的任务 invokeHandlerAddedIfNeeded(); //执行ChannelHandlerContext的 fireChannelRegistered方法 //8 -(16) ctx.fireChannelRegistered(); } //8 -(16) 头结点是outBound,此时下一个结点是ChannelInitializer为inBound,再下一个结点是DefaultChannelPipeline$TailContext为inBound。必须是inBound的入栈ChannelHandler才可以执行成功fireChannelRegistered方法 private AbstractChannelHandlerContext findContextInbound() { AbstractChannelHandlerContext ctx = this; do { ctx = ctx.next; } while (!ctx.inbound); return ctx; } //除了第一个ChannelInitializer是初始化就加进pipeline,后面的匿名ChannelHnadler和ServerBootstrapAcceptor都是异步的
来源:CSDN
作者:路人是妖怪
链接:https://blog.csdn.net/qq_41301079/article/details/103695763