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); } }

 

posted on 2019-09-24 00:49  iscys  阅读(452)  评论(0)    收藏  举报