netty 源码分析(二)

服务端启动源码


启动代码

    public static void main(String[] args) throws Exception {
        //创建两组eventLoop 一组用于客户端接入处理,另一个用于所有客户端
        //其它事件处理.
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new RouterServerHandlerV2());
                    }
                });
            ChannelFuture f = b.bind(PORT).sync();
            // Wait until the server socket is closed.
            f.channel().closeFuture().sync();
        } finally {
            // Shut down all event loops to terminate all threads.
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

1.配置EventLoopGroup,EventLoop

  1. 上面给ServerBootstrap添加两组eventLoop ,bossGroup 专门为客户端socket接入封装,并注册到workerGroup 事件线程组上,ServerSocketChannel是绑定到bossGroup 上的,SocketChannel被绑定到workerGroup;NioEventLoopGroup 默认线程数为cpu核数的2倍;bossGroup可据客户端接入并发量来设定线程,例如客户端接入并发量不大,可只设置一个线程数就行了
  2. NioEventLoopGroup 源码实现
    在这里插入图片描述
    public NioEventLoopGroup(int nThreads, Executor executor) {
        //绑定单例SelectorProvider
        this(nThreads, executor, SelectorProvider.provider());
    }
        public NioEventLoopGroup(
            int nThreads, ThreadFactory threadFactory, final SelectorProvider selectorProvider) {
               //绑定默认的Select 策略
        this(nThreads, threadFactory, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
    }
    
   protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
       //如果没有设置线程数,则设备cpu 核 数的两倍
        super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
    }
       protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
       //DefaultEventExecutorChooserFactory 轮询处理Executor 负载 ,实质相当于EventExecutor一个负载均衡器
        this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);
    }
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
                                            EventExecutorChooserFactory chooserFactory, Object... args) {
         //省去一些代码
         //ThreadPerTaskExecutor 只是简单实现Executor execute方法内new 一个组程并执行
        if (executor == null) {
            executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
        }
        //据线程数设置eventLoop 数组大小
        children = new EventExecutor[nThreads];
        for (int i = 0; i < nThreads; i ++) {
            boolean success = false;
            try {
               //创建子的EventLoop 这里根据实现,创建的是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 {
               //省去一些代码
            }
        }
        //据上面刚创建的NioEventLoop 放入EventExecutor 负载均衡器
        chooser = chooserFactory.newChooser(children);
         //省去一些代码
    }
    //创建NioEventLopp 
   @Override
    protected EventLoop newChild(Executor executor, Object... args) throws Exception {
        return new NioEventLoop(this, executor, (SelectorProvider) args[0],
            ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
    }
  1. 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;
       //打开selector
        final SelectorTuple selectorTuple = openSelector();
        selector = selectorTuple.selector;
        unwrappedSelector = selectorTuple.unwrappedSelector;
        selectStrategy = strategy;
    }
    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        if (childGroup == null) {
            throw new NullPointerException("childGroup");
        }
        if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        }
        this.childGroup = childGroup;
        return this;
    }

2.配置Channel实现类型

//设置channel工厂

    public B channel(Class<? extends C> channelClass) {
        if (channelClass == null) {
            throw new NullPointerException("channelClass");
        }
        return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
    }

//子channel处理器初始化回调

    public ServerBootstrap childHandler(ChannelHandler childHandler) {
        if (childHandler == null) {
            throw new NullPointerException("childHandler");
        }
        this.childHandler = childHandler;
        return this;
    }

3.服务端绑定地址端口,并注册ServerSocketChannel

AbstractBootstrap

 private ChannelFuture doBind(final SocketAddress localAddress) {
       //注册nioServerSocketChannel 并注册到一个EventLoop上
        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 {
           //省去一些代码
            return promise;
        }
    }
     final ChannelFuture initAndRegister() {
        Channel channel = null;
        try {
           //创建前面绑定的NioServerSocketChannel 类型的实例
           //在创建channel同时已经给其配置了一个DefaultChannelPipeline
            channel = channelFactory.newChannel();
            //初始化channel信息
            init(channel);
        } catch (Throwable t) {
           //省去一些代码
        }
        //给channe绑定eventloop(NioEventLoop)
        ChannelFuture regFuture = config().group().register(channel);
        return regFuture;
    }
    //初始化channel信息
      @Override
    void init(Channel channel) throws Exception {
        final Map<ChannelOption<?>, Object> options = options0();
        synchronized (options) {
            setChannelOptions(channel, options, logger);
        }

        final Map<AttributeKey<?>, Object> attrs = attrs0();
        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(0));
        }
        synchronized (childAttrs) {
            currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
        }

        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() {
                         //ServerBootstrapAcceptor 传入子group ,用于接入客户接入时,给客户端channel绑定到该group去
                        pipeline.addLast(new ServerBootstrapAcceptor(
                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });
    }

4.注册ServerSocketChannel 到EventLoop

  1. 绑定eventloop
    SingleThreadEventLoop
    @Override
    public ChannelFuture register(final ChannelPromise promise) {
        ObjectUtil.checkNotNull(promise, "promise");
        promise.channel().unsafe().register(this, promise);
        return promise;
    }

AbstractUnsafe

public final void register(EventLoop eventLoop, final ChannelPromise promise) {
            //省去一些代码,设置当前channel的eventloop
            AbstractChannel.this.eventLoop = eventLoop;

            if (eventLoop.inEventLoop()) {
                register0(promise);
            } else {
                try {
                    eventLoop.execute(new Runnable() {
                        @Override
                        public void run() {
                            register0(promise);
                        }
                    });
                } catch (Throwable t) {
                  //
                }
            }
        }

        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;
                //开始实质性注册到底层
                doRegister();
                neverRegistered = false;
                registered = true;
                //省去一些代码
        }

AbstractNioChannel
注册到底层的nio去

    @Override
    protected void doRegister() throws Exception {
        boolean selected = false;
        for (;;) {
            try {
            // ServerSocketChannelImpl.regiest 这里是jdk里的实现了
                selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
                return;
            } catch (CancelledKeyException e) {
               //省略一些消息
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值