netty 总结服务端启动流程

这一生的挚爱 提交于 2020-08-16 20:00:39

主要是贴代码

给自己做个总结(连接服务端初始化以及处理):

1. NioEventLoop 用来正真处理io连接的

2.NioEventLoopGroup 可以简单的理解为处理组一共两个,一个是接受连接的,一个是处理连接的,里面的chooser即是NioEventLoop数组

服务端初始化流程

入口
ChannelFuture f = b.bind(8888).sync();

   

public ChannelFuture bind(int inetPort) {
        return this.bind(new InetSocketAddress(inetPort));
    }
    
    public ChannelFuture bind(SocketAddress localAddress) {
        this.validate();
        if (localAddress == null) {
            throw new NullPointerException("localAddress");
        } else {
            return this.doBind(localAddress);
        }
    }


    private ChannelFuture doBind(final SocketAddress localAddress) {
        //初始化即注册
        final ChannelFuture regFuture = this.initAndRegister();
        final Channel channel = regFuture.channel();
        if (regFuture.cause() != null) {
            return regFuture;
        } else if (regFuture.isDone()) {
            ChannelPromise promise = channel.newPromise();
            //绑定
            doBind0(regFuture, channel, localAddress, promise);
            return promise;
        } else {
            final AbstractBootstrap.PendingRegistrationPromise promise = new AbstractBootstrap.PendingRegistrationPromise(channel);
            regFuture.addListener(new ChannelFutureListener() {
                public void operationComplete(ChannelFuture future) throws Exception {
                    Throwable cause = future.cause();
                    if (cause != null) {
                        promise.setFailure(cause);
                    } else {
                        promise.registered();
                        AbstractBootstrap.doBind0(regFuture, channel, localAddress, promise);
                    }

                }
            });
            return promise;
        }
    }
    先说注册以及初始化
    final ChannelFuture initAndRegister() {
        Channel channel = null;

        try {
            //这里的channelFactory是启动代码的 b.channel(NioServerSocketChannel.class)传的通过反射实例化的对象
            channel = this.channelFactory.newChannel();
            //初始化
            this.init(channel);
        } catch (Throwable var3) {
            if (channel != null) {
                channel.unsafe().closeForcibly();
                return (new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE)).setFailure(var3);
            }

            return (new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE)).setFailure(var3);
        }

        //注册selector
        ChannelFuture regFuture = this.config().group().register(channel);
        if (regFuture.cause() != null) {
            if (channel.isRegistered()) {
                channel.close();
            } else {
                channel.unsafe().closeForcibly();
            }
        }

        return regFuture;
    }    
    
    //设置ChannelOptions ChannelAttrs     配置服务端Channel的相关属性
    //设置ChildOptions ChildAttrs    配置每个新连接的Channel的相关属性
    //Config handler    配置服务端pipeline
    //add ServerBootstrapAcceptor    添加连接器,对accpet接受到的新连接进行处理,添加一个nio线程
    void init(Channel channel) throws Exception {
        Map<ChannelOption<?>, Object> options = this.options0();
        synchronized(options) {
            setChannelOptions(channel, options, logger);
        }

        Map<AttributeKey<?>, Object> attrs = this.attrs0();
        synchronized(attrs) {
            Iterator var5 = attrs.entrySet().iterator();

            while(true) {
                if (!var5.hasNext()) {
                    break;
                }

                Entry<AttributeKey<?>, Object> e = (Entry)var5.next();
                AttributeKey<Object> key = (AttributeKey)e.getKey();
                channel.attr(key).set(e.getValue());
            }
        }

        ChannelPipeline p = channel.pipeline();
        final EventLoopGroup currentChildGroup = this.childGroup;
        final ChannelHandler currentChildHandler = this.childHandler;
        Map var9 = this.childOptions;
        final Entry[] currentChildOptions;
        synchronized(this.childOptions) {
            currentChildOptions = (Entry[])this.childOptions.entrySet().toArray(newOptionArray(this.childOptions.size()));
        }

        var9 = this.childAttrs;
        final Entry[] currentChildAttrs;
        synchronized(this.childAttrs) {
            currentChildAttrs = (Entry[])this.childAttrs.entrySet().toArray(newAttrArray(this.childAttrs.size()));
        }

        p.addLast(new ChannelHandler[]{new ChannelInitializer<Channel>() {
            public void initChannel(final Channel ch) throws Exception {
                final ChannelPipeline pipeline = ch.pipeline();
                ChannelHandler handler = ServerBootstrap.this.config.handler();
                if (handler != null) {
                    pipeline.addLast(new ChannelHandler[]{handler});
                }

                ch.eventLoop().execute(new Runnable() {
                    public void run() {
                        //这里是在有了新连接接入的时候生成处理NioEventLoop的后续会讲到
                        pipeline.addLast(new ChannelHandler[]{new ServerBootstrap.ServerBootstrapAcceptor(ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)});
                    }
                });
            }
        }});
    }

    接下来注册selector
   

public ChannelFuture register(Channel channel) {
        return this.next().register(channel);
    }
    public EventLoop next() {
        return (EventLoop)super.next();
    }
    public EventExecutor next() {
        return this.chooser.next();
    }


    从上面的代码我们可以看到其实调用的    NioEventLoop(父类) 的register方法   SingleThreadEventLoop
   

 public ChannelFuture register(Channel channel) {
        return this.register((ChannelPromise)(new DefaultChannelPromise(channel, this)));
    }

    public ChannelFuture register(ChannelPromise promise) {
        ObjectUtil.checkNotNull(promise, "promise");
        promise.channel().unsafe().register(this, promise);
        return promise;
    }

    最终调用的是io.netty.channel.AbstractChannel.AbstractUnsafe
   

public final void register(EventLoop eventLoop, final ChannelPromise promise) {
        if (eventLoop == null) {
            throw new NullPointerException("eventLoop");
        } else if (AbstractChannel.this.isRegistered()) {
            promise.setFailure(new IllegalStateException("registered to an event loop already"));
        } else if (!AbstractChannel.this.isCompatible(eventLoop)) {
            promise.setFailure(new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
        } else {
            //赋值 将NioEventLoop与channel绑定
            AbstractChannel.this.eventLoop = eventLoop;
            if (eventLoop.inEventLoop()) {
                //注册流程
                this.register0(promise);
            } else {
                try {
                    eventLoop.execute(new Runnable() {
                        public void run() {
                            AbstractUnsafe.this.register0(promise);
                        }
                    });
                } catch (Throwable var4) {
                    AbstractChannel.logger.warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", AbstractChannel.this, var4);
                    this.closeForcibly();
                    AbstractChannel.this.closeFuture.setClosed();
                    this.safeSetFailure(promise, var4);
                }
            }

        }
    }    

    private void register0(ChannelPromise promise) {
        try {
            if (!promise.setUncancellable() || !this.ensureOpen(promise)) {
                return;
            }

            boolean firstRegistration = this.neverRegistered;
            //这里
            AbstractChannel.this.doRegister();
            this.neverRegistered = false;
            AbstractChannel.this.registered = true;
            //执行这个方法的原因是 当pipeline调用的时候,如果该 pipeline 还没有注册到这个 eventLoop 上,则将这个包装过 handler 的 context 放进变量 pendingHandlerCallbackHead 中,然后在此执行
            AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded();
            this.safeSetSuccess(promise);
            AbstractChannel.this.pipeline.fireChannelRegistered();
            if (AbstractChannel.this.isActive()) {
                if (firstRegistration) {
                    AbstractChannel.this.pipeline.fireChannelActive();
                } else if (AbstractChannel.this.config().isAutoRead()) {
                    this.beginRead();
                }
            }
        } catch (Throwable var3) {
            this.closeForcibly();
            AbstractChannel.this.closeFuture.setClosed();
            this.safeSetFailure(promise, var3);
        }

    }
    
    
    protected void doRegister() throws Exception {
        boolean selected = false;
        for (;;) {
            try {
                //把channel注册到eventLoop上的selector上 jdk
                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;
                }
            }
        }
    }


    
    
    开始绑定
    这时候服务端处理的NioEventLoop就已经在运行了  channel.eventLoop().execute()就已经触发了run方法
   

private static void doBind0(final ChannelFuture regFuture, final Channel channel, final SocketAddress localAddress, final ChannelPromise promise) {
        channel.eventLoop().execute(new Runnable() {
            public void run() {
                if (regFuture.isSuccess()) {
                    channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
                } else {
                    promise.setFailure(regFuture.cause());
                }

            }
        });
    }

    public void execute(Runnable task) {
        if (task == null) {
            throw new NullPointerException("task");
        } else {
            boolean inEventLoop = this.inEventLoop();
            if (inEventLoop) {
                this.addTask(task);
            } else {
                //新起一个线程
                this.startThread();
                this.addTask(task);
                if (this.isShutdown() && this.removeTask(task)) {
                    reject();
                }
            }

            if (!this.addTaskWakesUp && this.wakesUpForTask(task)) {
                this.wakeup(inEventLoop);
            }

        }
    }

    private void startThread() {
        if (this.state == 1 && STATE_UPDATER.compareAndSet(this, 1, 2)) {
            try {
                this.doStartThread();
            } catch (Throwable var2) {
                STATE_UPDATER.set(this, 1);
                PlatformDependent.throwException(var2);
            }
        }

    }    
    
    private void doStartThread() {
        assert this.thread == null;

        this.executor.execute(new Runnable() {
            public void run() {
                SingleThreadEventExecutor.this.thread = Thread.currentThread();
                if (SingleThreadEventExecutor.this.interrupted) {
                    SingleThreadEventExecutor.this.thread.interrupt();
                }

                boolean success = false;
                SingleThreadEventExecutor.this.updateLastExecutionTime();
                boolean var112 = false;

                int oldState;
                label1685: {
                    try {
                        var112 = true;
                        //这步其实调用的就是NioEventLoop的run方法
                        SingleThreadEventExecutor.this.run();
                        success = true;
                        var112 = false;
                        break label1685;
                    } catch (Throwable var119) {
                        SingleThreadEventExecutor.logger.warn("Unexpected exception from an event executor: ", var119);
                        var112 = false;
                    } finally {
                        if (var112) {
                            int oldStatex;
                            do {
                                oldStatex = SingleThreadEventExecutor.this.state;
                            } while(oldStatex < 3 && !SingleThreadEventExecutor.STATE_UPDATER.compareAndSet(SingleThreadEventExecutor.this, oldStatex, 3));

                            if (success && SingleThreadEventExecutor.this.gracefulShutdownStartTime == 0L) {
                                SingleThreadEventExecutor.logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " + SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called before run() implementation terminates.");
                            }

                            try {
                                while(!SingleThreadEventExecutor.this.confirmShutdown()) {
                                    ;
                                }
                            } finally {
                                try {
                                    SingleThreadEventExecutor.this.cleanup();
                                } finally {
                                    SingleThreadEventExecutor.STATE_UPDATER.set(SingleThreadEventExecutor.this, 5);
                                    SingleThreadEventExecutor.this.threadLock.release();
                                    if (!SingleThreadEventExecutor.this.taskQueue.isEmpty()) {
                                        SingleThreadEventExecutor.logger.warn("An event executor terminated with non-empty task queue (" + SingleThreadEventExecutor.this.taskQueue.size() + ')');
                                    }

                                    SingleThreadEventExecutor.this.terminationFuture.setSuccess((Object)null);
                                }
                            }

                        }
                    }

                    do {
                        oldState = SingleThreadEventExecutor.this.state;
                    } while(oldState < 3 && !SingleThreadEventExecutor.STATE_UPDATER.compareAndSet(SingleThreadEventExecutor.this, oldState, 3));

                    if (success && SingleThreadEventExecutor.this.gracefulShutdownStartTime == 0L) {
                        SingleThreadEventExecutor.logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " + SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called before run() implementation terminates.");
                    }

                    try {
                        while(!SingleThreadEventExecutor.this.confirmShutdown()) {
                            ;
                        }

                        return;
                    } finally {
                        try {
                            SingleThreadEventExecutor.this.cleanup();
                        } finally {
                            SingleThreadEventExecutor.STATE_UPDATER.set(SingleThreadEventExecutor.this, 5);
                            SingleThreadEventExecutor.this.threadLock.release();
                            if (!SingleThreadEventExecutor.this.taskQueue.isEmpty()) {
                                SingleThreadEventExecutor.logger.warn("An event executor terminated with non-empty task queue (" + SingleThreadEventExecutor.this.taskQueue.size() + ')');
                            }

                            SingleThreadEventExecutor.this.terminationFuture.setSuccess((Object)null);
                        }
                    }
                }

                do {
                    oldState = SingleThreadEventExecutor.this.state;
                } while(oldState < 3 && !SingleThreadEventExecutor.STATE_UPDATER.compareAndSet(SingleThreadEventExecutor.this, oldState, 3));

                if (success && SingleThreadEventExecutor.this.gracefulShutdownStartTime == 0L) {
                    SingleThreadEventExecutor.logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " + SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called before run() implementation terminates.");
                }

                try {
                    while(!SingleThreadEventExecutor.this.confirmShutdown()) {
                        ;
                    }
                } finally {
                    try {
                        SingleThreadEventExecutor.this.cleanup();
                    } finally {
                        SingleThreadEventExecutor.STATE_UPDATER.set(SingleThreadEventExecutor.this, 5);
                        SingleThreadEventExecutor.this.threadLock.release();
                        if (!SingleThreadEventExecutor.this.taskQueue.isEmpty()) {
                            SingleThreadEventExecutor.logger.warn("An event executor terminated with non-empty task queue (" + SingleThreadEventExecutor.this.taskQueue.size() + ')');
                        }

                        SingleThreadEventExecutor.this.terminationFuture.setSuccess((Object)null);
                    }
                }

            }
        });
    }

    继续看绑定

public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
        return this.pipeline.bind(localAddress, promise);
    }

   
   接下来是内部的pipeline调用链
   

public final ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
        return this.tail.bind(localAddress, promise);
    }

    public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) {
        if (localAddress == null) {
            throw new NullPointerException("localAddress");
        } else if (this.isNotValidPromise(promise, false)) {
            return promise;
        } else {
            final AbstractChannelHandlerContext next = this.findContextOutbound();
            EventExecutor executor = next.executor();
            if (executor.inEventLoop()) {
                next.invokeBind(localAddress, promise);
            } else {
                safeExecute(executor, new Runnable() {
                    public void run() {
                        next.invokeBind(localAddress, promise);
                    }
                }, promise, (Object)null);
            }

            return promise;
        }
    }
    
    //最终调用的是heade的unsafe.bind
    public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
        this.unsafe.bind(localAddress, promise);
    }

    public final void bind(SocketAddress localAddress, ChannelPromise promise) {
        this.assertEventLoop();
        if (promise.setUncancellable() && this.ensureOpen(promise)) {
            if (Boolean.TRUE.equals(AbstractChannel.this.config().getOption(ChannelOption.SO_BROADCAST)) && localAddress instanceof InetSocketAddress && !((InetSocketAddress)localAddress).getAddress().isAnyLocalAddress() && !PlatformDependent.isWindows() && !PlatformDependent.maybeSuperUser()) {
                AbstractChannel.logger.warn("A non-root user can't receive a broadcast packet if the socket is not bound to a wildcard address; binding to a non-wildcard address (" + localAddress + ") anyway as requested.");
            }

            boolean wasActive = AbstractChannel.this.isActive();

            try {
                AbstractChannel.this.doBind(localAddress);
            } catch (Throwable var5) {
                this.safeSetFailure(promise, var5);
                this.closeIfClosed();
                return;
            }

            if (!wasActive && AbstractChannel.this.isActive()) {
                this.invokeLater(new Runnable() {
                    public void run() {
                        AbstractChannel.this.pipeline.fireChannelActive();
                    }
                });
            }

            this.safeSetSuccess(promise);
        }
    }
    
    //绑定
    protected void doBind(SocketAddress localAddress) throws Exception {
        if (PlatformDependent.javaVersion() >= 7) {
            this.javaChannel().bind(localAddress, this.config.getBacklog());
        } else {
            this.javaChannel().socket().bind(localAddress, this.config.getBacklog());
        }

    }    

    public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
        return this.pipeline.bind(localAddress, promise);
    }


    public final ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
        return this.tail.bind(localAddress, promise);
    }
    //HeadContext
    public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
        this.unsafe.bind(localAddress, promise);
    }

    public final void bind(SocketAddress localAddress, ChannelPromise promise) {
        this.assertEventLoop();
        if (promise.setUncancellable() && this.ensureOpen(promise)) {
            if (Boolean.TRUE.equals(AbstractChannel.this.config().getOption(ChannelOption.SO_BROADCAST)) && localAddress instanceof InetSocketAddress && !((InetSocketAddress)localAddress).getAddress().isAnyLocalAddress() && !PlatformDependent.isWindows() && !PlatformDependent.maybeSuperUser()) {
                AbstractChannel.logger.warn("A non-root user can't receive a broadcast packet if the socket is not bound to a wildcard address; binding to a non-wildcard address (" + localAddress + ") anyway as requested.");
            }

            boolean wasActive = AbstractChannel.this.isActive();

            try {
                //jdk 绑定
                AbstractChannel.this.doBind(localAddress);
            } catch (Throwable var5) {
                this.safeSetFailure(promise, var5);
                this.closeIfClosed();
                return;
            }

            if (!wasActive && AbstractChannel.this.isActive()) {
                //注意 此时才是active 状态 执行下面的流程
                this.invokeLater(new Runnable() {
                    public void run() {
                        AbstractChannel.this.pipeline.fireChannelActive();
                    }
                });
            }

            this.safeSetSuccess(promise);
        }
    }
    //调用jdk绑定端口    
    protected void doBind(SocketAddress localAddress) throws Exception {
        if (PlatformDependent.javaVersion() >= 7) {
            this.javaChannel().bind(localAddress, this.config.getBacklog());
        } else {
            this.javaChannel().socket().bind(localAddress, this.config.getBacklog());
        }

    }


    后续处理
   

public final ChannelPipeline fireChannelActive() {
        AbstractChannelHandlerContext.invokeChannelActive(this.head);
        return this;
    }
    //在head中 还会处理readIfIsAutoRead
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelActive();
        this.readIfIsAutoRead();
    }

        private void readIfIsAutoRead() {
            if (DefaultChannelPipeline.this.channel.config().isAutoRead()) {
                DefaultChannelPipeline.this.channel.read();
            }

        }

    public Channel read() {
        this.pipeline.read();
        return this;
    }    
    
    public final ChannelPipeline read() {
        this.tail.read();
        return this;
    }
    //最终还是到了head 中的unsafe方法  服务监控链接的NioEventLoop 的unsafe 是NioMessageUnsafe  
    public void read(ChannelHandlerContext ctx) {
        this.unsafe.beginRead();
    }    

    public final void beginRead() {
        this.assertEventLoop();
        if (AbstractChannel.this.isActive()) {
            try {
                AbstractChannel.this.doBeginRead();
            } catch (final Exception var2) {
                this.invokeLater(new Runnable() {
                    public void run() {
                        AbstractChannel.this.pipeline.fireExceptionCaught(var2);
                    }
                });
                this.close(this.voidPromise());
            }

        }
    }


            注册SelectionKey.OP_ACCEPT事件 至此 服务端启动完毕  NioEventLoop 也在运行中for(;;)
   

protected void doBeginRead() throws Exception {
        SelectionKey selectionKey = this.selectionKey;
        if (selectionKey.isValid()) {
            this.readPending = true;
            int interestOps = selectionKey.interestOps();
            if ((interestOps & this.readInterestOp) == 0) {
                selectionKey.interestOps(interestOps | this.readInterestOp);
            }

        }
    }


总结:初始化NioEventLoop 这是无限监听线程的封装  初始化channel  绑定NioEventLoop  绑定端口 注册 SelectionKey.OP_ACCEPT

新连接接入
入口
io.netty.channel.nio.NioEventLoop#run 无限循环监听 当有链接进入的时候调用链如下
   

protected void run() {
        while(true) {
            while(true) {
                try {
                    switch(this.selectStrategy.calculateStrategy(this.selectNowSupplier, this.hasTasks())) {
                    case -2:
                        continue;
                    case -1:
                        //select 操作
                        this.select(this.wakenUp.getAndSet(false));
                        if (this.wakenUp.get()) {
                            this.selector.wakeup();
                        }
                    default:
                        this.cancelledKeys = 0;
                        this.needsToSelectAgain = false;
                        int ioRatio = this.ioRatio;
                        if (ioRatio == 100) {
                            try {
                                //有链接的时候调用这个
                                this.processSelectedKeys();
                            } finally {
                                this.runAllTasks();
                            }
                        } else {
                            long ioStartTime = System.nanoTime();
                            boolean var13 = false;

                            try {
                                var13 = true;
                                this.processSelectedKeys();
                                var13 = false;
                            } finally {
                                if (var13) {
                                    long ioTime = System.nanoTime() - ioStartTime;
                                    this.runAllTasks(ioTime * (long)(100 - ioRatio) / (long)ioRatio);
                                }
                            }

                            long ioTime = System.nanoTime() - ioStartTime;
                            this.runAllTasks(ioTime * (long)(100 - ioRatio) / (long)ioRatio);
                        }
                    }
                } catch (Throwable var21) {
                    handleLoopException(var21);
                }

                try {
                    if (this.isShuttingDown()) {
                        this.closeAll();
                        if (this.confirmShutdown()) {
                            return;
                        }
                    }
                } catch (Throwable var18) {
                    handleLoopException(var18);
                }
            }
        }
    }

    private void processSelectedKeys() {
        if (this.selectedKeys != null) {
            this.processSelectedKeysOptimized();
        } else {
            this.processSelectedKeysPlain(this.selector.selectedKeys());
        }

    }
    
    private void processSelectedKeysOptimized() {
        for(int i = 0; i < this.selectedKeys.size; ++i) {
            SelectionKey k = this.selectedKeys.keys[i];
            this.selectedKeys.keys[i] = null;
            Object a = k.attachment();
            if (a instanceof AbstractNioChannel) {
                this.processSelectedKey(k, (AbstractNioChannel)a);
            } else {
                NioTask<SelectableChannel> task = (NioTask)a;
                processSelectedKey(k, task);
            }

            if (this.needsToSelectAgain) {
                this.selectedKeys.reset(i + 1);
                this.selectAgain();
                i = -1;
            }
        }

    }

    //这个方法
    private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
        NioUnsafe unsafe = ch.unsafe();
        if (!k.isValid()) {
            NioEventLoop eventLoop;
            try {
                eventLoop = ch.eventLoop();
            } catch (Throwable var6) {
                return;
            }

            if (eventLoop == this && eventLoop != null) {
                unsafe.close(unsafe.voidPromise());
            }
        } else {
            try {
                int readyOps = k.readyOps();
                if ((readyOps & 8) != 0) {
                    int ops = k.interestOps();
                    ops &= -9;
                    k.interestOps(ops);
                    unsafe.finishConnect();
                }

                if ((readyOps & 4) != 0) {
                    ch.unsafe().forceFlush();
                }

                if ((readyOps & 17) != 0 || readyOps == 0) {
                    //其实最终调用的是这个方法
                    unsafe.read();
                }
            } catch (CancelledKeyException var7) {
                unsafe.close(unsafe.voidPromise());
            }

        }
    }


        public void read() {
            assert AbstractNioMessageChannel.this.eventLoop().inEventLoop();

            ChannelConfig config = AbstractNioMessageChannel.this.config();
            ChannelPipeline pipeline = AbstractNioMessageChannel.this.pipeline();
            Handle allocHandle = AbstractNioMessageChannel.this.unsafe().recvBufAllocHandle();
            allocHandle.reset(config);
            boolean closed = false;
            Throwable exception = null;

            try {
                int localRead;
                try {
                    do {
                        localRead = AbstractNioMessageChannel.this.doReadMessages(this.readBuf);
                        if (localRead == 0) {
                            break;
                        }

                        if (localRead < 0) {
                            closed = true;
                            break;
                        }

                        allocHandle.incMessagesRead(localRead);
                    } while(allocHandle.continueReading());
                } catch (Throwable var11) {
                    exception = var11;
                }

                localRead = this.readBuf.size();

                for(int i = 0; i < localRead; ++i) {
                    AbstractNioMessageChannel.this.readPending = false;
                    //这块很关键  最终是一个 head->unsafe->ServerBootstrapAcceptor的调用链
                    pipeline.fireChannelRead(this.readBuf.get(i));
                }

                this.readBuf.clear();
                allocHandle.readComplete();
                pipeline.fireChannelReadComplete();
                if (exception != null) {
                    closed = AbstractNioMessageChannel.this.closeOnReadError(exception);
                    pipeline.fireExceptionCaught(exception);
                }

                if (closed) {
                    AbstractNioMessageChannel.this.inputShutdown = true;
                    if (AbstractNioMessageChannel.this.isOpen()) {
                        this.close(this.voidPromise());
                    }
                }
            } finally {
                if (!AbstractNioMessageChannel.this.readPending && !config.isAutoRead()) {
                    this.removeReadOp();
                }

            }

        }


    接受链接 accept  add到buf list
   

protected int doReadMessages(List<Object> buf) throws Exception {
        SocketChannel ch = SocketUtils.accept(this.javaChannel());

        try {
            if (ch != null) {
                //this 为服务端channel,即NioServerSocketChannel    ch 为jdk创建的客户端channel ch 里面的 readInterestOp为SelectionKey.OP_READ
                buf.add(new NioSocketChannel(this, ch));
                return 1;
            }
        } catch (Throwable var6) {
            logger.warn("Failed to create a new channel from an accepted socket.", var6);

            try {
                ch.close();
            } catch (Throwable var5) {
                logger.warn("Failed to close a socket.", var5);
            }
        }


ServerBootstrapAcceptor 

        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            final Channel child = (Channel) msg;
            //添加业务handler
            //流程如下  io.netty.channel.DefaultChannelPipeline#addLast(io.netty.channel.ChannelHandler...)   
            //io.netty.channel.DefaultChannelPipeline#addLast(io.netty.util.concurrent.EventExecutorGroup, io.netty.channel.ChannelHandler...)
            //io.netty.channel.DefaultChannelPipeline#addLast(io.netty.util.concurrent.EventExecutorGroup, java.lang.String, io.netty.channel.ChannelHandler)
            //io.netty.channel.DefaultChannelPipeline#callHandlerAdded0
            //io.netty.channel.AbstractChannelHandlerContext#callHandlerAdded
            // handler().handlerAdded(this);  业务加的自定义ChannelInitializer 里面的handlerAdded 方法其实就是调用initChannel方法 也就是我们加handle的常用方式
            child.pipeline().addLast(childHandler);

            setChannelOptions(child, childOptions, logger);
            setAttributes(child, childAttrs);

            try {
                //register 过程与服务端监听的channel大致差不多  
                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);
            }
        }

//workerGroup
public ChannelFuture register(Channel channel) {
    return this.next().register(channel);
}

public ChannelFuture register(Channel channel, ChannelPromise promise) {
    if(channel == null) {
        throw new NullPointerException("channel");
    } else if(promise == null) {
        throw new NullPointerException("promise");
    } else {
        //这里的unsafe是NioSocketChannel$NioSocketChannelUnsafe
        channel.unsafe().register(this, promise);
        return promise;
    }
}

public final void register(EventLoop eventLoop, final ChannelPromise promise) {
    if(eventLoop == null) {
        throw new NullPointerException("eventLoop");
    } else if(AbstractChannel.this.isRegistered()) {
        promise.setFailure(new IllegalStateException("registered to an event loop already"));
    } else if(!AbstractChannel.this.isCompatible(eventLoop)) {
        promise.setFailure(new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
    } else {
        AbstractChannel.this.eventLoop = eventLoop;
        // 开始真正的异步  此时线程是boss线程 而不是worder线程 会异步  同时启动NioEventLoop的run方法
        if(eventLoop.inEventLoop()) {
            this.register0(promise);
        } else {
            try {
                eventLoop.execute(new OneTimeTask() {
                    public void run() {
                        AbstractUnsafe.this.register0(promise);
                    }
                });
            } catch (Throwable var4) {
                AbstractChannel.logger.warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", AbstractChannel.this, var4);
                this.closeForcibly();
                AbstractChannel.this.closeFuture.setClosed();
                this.safeSetFailure(promise, var4);
            }
        }
 
    }
}

//同上
private void register0(ChannelPromise promise) {
}


protected void doRegister() throws Exception {
    boolean selected = false;
 
    while(true) {
        try {
            this.selectionKey = this.javaChannel().register(this.eventLoop().selector, 0, this);
            return;
        } catch (CancelledKeyException var3) {
            if(selected) {
                throw var3;
            }
 
            this.eventLoop().selectNow();
            selected = true;
        }
    }
}

public ChannelPipeline fireChannelActive() {
    this.head.fireChannelActive();
    if(this.channel.config().isAutoRead()) {
        this.channel.read();
    }
 
    return this;
}


public ChannelHandlerContext read() {
    final AbstractChannelHandlerContext next = this.findContextOutbound();
    EventExecutor executor = next.executor();
    if(executor.inEventLoop()) {
        next.invokeRead();
    } else {
        Runnable task = next.invokeReadTask;
        if(task == null) {
            next.invokeReadTask = task = new Runnable() {
                public void run() {
                    next.invokeRead();
                }
            };
        }
 
        executor.execute(task);
    }
 
    return this;
}

protected void doBeginRead() throws Exception {
    if(!this.inputShutdown) {
        SelectionKey selectionKey = this.selectionKey;
        if(selectionKey.isValid()) {
            this.readPending = true;
            int interestOps = selectionKey.interestOps();
            if((interestOps & this.readInterestOp) == 0) {
                selectionKey.interestOps(interestOps | this.readInterestOp);
            }
 
        }
    }
}

当客户端链接有读事件时,也会调用unsafe.read()方法 不过此时unsafe是NioByteUnsafe
       

 public final void read() {
            final ChannelConfig config = config();
            final ChannelPipeline pipeline = pipeline();
            final ByteBufAllocator allocator = config.getAllocator();
            final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
            allocHandle.reset(config);

            ByteBuf byteBuf = null;
            boolean close = false;
            try {
                do {
                    byteBuf = allocHandle.allocate(allocator);
                    allocHandle.lastBytesRead(doReadBytes(byteBuf));
                    if (allocHandle.lastBytesRead() <= 0) {
                        // nothing was read. release the buffer.
                        byteBuf.release();
                        byteBuf = null;
                        close = allocHandle.lastBytesRead() < 0;
                        break;
                    }

                    allocHandle.incMessagesRead(1);
                    readPending = false;
                    //这里 从而实现了处理数据的能力
                    pipeline.fireChannelRead(byteBuf);
                    byteBuf = null;
                } while (allocHandle.continueReading());

                allocHandle.readComplete();
                pipeline.fireChannelReadComplete();

                if (close) {
                    closeOnRead(pipeline);
                }
            } catch (Throwable t) {
                handleReadException(pipeline, byteBuf, t, close, allocHandle);
            } finally {
              
                if (!readPending && !config.isAutoRead()) {
                    removeReadOp();
                }
            }
        }
    }


    

        
netty是在哪里检测到有新连接接入的?
boss线程执行的第一个过程,轮询出accpet事件,然后第二个过程通过jdk底层的accept方法,去创建这个连接
新连接时怎么注册到NioEventLoop线程的
简单来说,boss线程通过获取chooser的next()方法,拿到一个NioEventLoop。然后将新连接注册到这个NioEventLoop上的selector。

一个NioEventLoop对应一个selector

pipeline
在AbstractChannel初始化

入站事件
ChannelPipeline中的传播顺序为:head ——> ...... ——> tail。
出站事件
ChannelPipeline中各个ChannelHandler的执行顺序是:tail ——> ...... ——> head。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!