五Netty源码分析--1NioEventLoopGroup初始化分析

五Netty源码分析--1NioEventLoopGroup初始化分析

以NettyRPC项目为例,源码分析:

 public void run() {
   							//netty的reactor线程组
                EventLoopGroup bossGroup = new NioEventLoopGroup();
                EventLoopGroup workerGroup = new NioEventLoopGroup();
                try {
                  	//服务端启动配置类
                    ServerBootstrap bootstrap = new ServerBootstrap();
                    bootstrap.group(bossGroup, workerGroup)
                      			.channel(NioServerSocketChannel.class)
                      			//server端parentchannel的option
                            .option(ChannelOption.SO_BACKLOG, 128)
                      			//server端childchannel的handler、option、attr等的配置
                            .childHandler(new RpcServerInitializer(serviceMap, threadPoolExecutor))
                            .childOption(ChannelOption.SO_KEEPALIVE, true);

                    String[] array = serverAddress.split(":");
                    String host = array[0];
                    int port = Integer.parseInt(array[1]);
                  	//绑定
                    ChannelFuture future = bootstrap.bind(host, port).sync();

                    if (serviceRegistry != null) {
                        serviceRegistry.registerService(host, port, serviceMap);
                    }
                    logger.info("Server started on port {}", port);
                    future.channel().closeFuture().sync();
                } catch (Exception e) {
                    if (e instanceof InterruptedException) {
                        logger.info("Rpc server remoting server stop");
                    } else {
                        logger.error("Rpc server remoting server error", e);
                    }
                } finally {
                  //资源回收
                    try {
                        serviceRegistry.unregisterService();
                        workerGroup.shutdownGracefully();
                        bossGroup.shutdownGracefully();
                    } catch (Exception ex) {
                        logger.error(ex.getMessage(), ex);
                    }
                }
            }
        });
        thread.start();
    }

Netty启动流程如下:

image-20230310161125821

Netty的启动和运行流程,需要结合NIO编程逻辑,关联性的学习。

第一节 NioEventLoopGroup初始化分析

TAG1 NioEventLoopGroup
public class NioEventLoopGroup extends MultithreadEventLoopGroup {

     public NioEventLoopGroup() {
        this(0);
    }

     public NioEventLoopGroup(int nEventLoops) {
        this(nEventLoops, (Executor) null);
    }
  
    public NioEventLoopGroup(int nEventLoops, Executor executor) {
      //executor 当前group所含的executor
      //provider:两个方法——provider()、openServerSocketChannel(用来创建原生serverSocketChannel)
        this(nEventLoops, executor, SelectorProvider.provider());
    }
  	
    public NioEventLoopGroup(
            int nThreads, Executor executor, final SelectorProvider selectorProvider) {
      	//传入策略选择器工厂类实例
        this(nThreads, executor, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
    }
  
    public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider,
                             final SelectStrategyFactory selectStrategyFactory) {
        super(nThreads, executor, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
    }
}

image-20221201163853659

TAG2 MultithreadEventLoopGroup
    protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
            //构造函数参数为0,初始换时设置为2*CPU数量
        super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
    }

无参构造group的过程中,线程数默认设置为2*CPU数量;

SelectorProvider.provider(),是当前JVM中唯一单例的provider对象。provider用来创建selector选择器、创建NIO原生serverSocketChannel。

TAG3 MultithreadEventExecutorGroup
    protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
      		//eventExecutor选择器工厂类(用来在group中选择
        this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);
    }

    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) {
//TAG3.1 ThreadPerTaskExecutor
       //该executor将来会传递到children内的NioEventLoop内,在调用nioEventLoop.execute()时,方法内调用executor.execute()创建线程
            executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
        }

      	//group内nioeventloop集合
        children = new EventExecutor[nThreads];

        for (int i = 0; i < nThreads; i ++) {
            boolean success = false;
            try {
//TAG3.2 newChild(executor, args)
              	//初始化group内的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 {
              //初始化children中任何一个nioeventloop创建失败,就遍历关闭
                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;
                        }
                    }
                }
            }
        }

      	//eventexecutor选择器
        chooser = chooserFactory.newChooser(children);

      	//netty的future、listener监听器机制
      //创建操作完成的监听器listener
        final FutureListener<Object> terminationListener = new FutureListener<Object>() {
            @Override
            public void operationComplete(Future<Object> future) throws Exception {
                if (terminatedChildren.incrementAndGet() == children.length) {
                    terminationFuture.setSuccess(null);
                }
            }
        };
				//为children每个EventExecutor添加终止时的监听器
        for (EventExecutor e: children) {
            e.terminationFuture().addListener(terminationListener);
        }

      	//将children集合内的eventloop,转换为set集合
        Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
        Collections.addAll(childrenSet, children);
        readonlyChildren = Collections.unmodifiableSet(childrenSet);
    }

在MultithreadEventExecutorGroup的构造函数中完成group真正的实例化过程。

TAG3.1 ThreadPerTaskExecutor(newDefaultThreadFactory())--group内executor
public final class ThreadPerTaskExecutor implements Executor {
    private final ThreadFactory threadFactory;

    public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
        if (threadFactory == null) {
            throw new NullPointerException("threadFactory");
        }
        this.threadFactory = threadFactory;
    }

  	//线程工厂创建新线程并启动
    @Override
    public void execute(Runnable command) {
        threadFactory.newThread(command).start();
    }
}

这个executor是group内对象,其execute()方法,通过线程工厂类创建新的线程并启动。

TAG3.2 newChild(executor, args)
NioEventLoopGroup

    @Override
  	//args参数是前面传入的汇总
    protected EventLoop newChild(Executor executor, Object... args) throws Exception {
        EventLoopTaskQueueFactory queueFactory = args.length == 4 ? (EventLoopTaskQueueFactory) args[3] : null;
//TAG3.2.1 NioEventLoop
        return new NioEventLoop(this, executor, (SelectorProvider) args[0],
            ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2], queueFactory);
    }

image-20221201171806236

TAG3.2.1 NioEventLoop

NioEventLoop中的executor,为NioEventLoopGroup中创建的ThreadPerTaskExecutor对象。

    NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
                 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
                 EventLoopTaskQueueFactory queueFactory) {
//TAG3.2.1.1 newTaskQueue
//TAG3.2.1.2 
        super(parent, executor, false, newTaskQueue(queueFactory), newTaskQueue(queueFactory),
                rejectedExecutionHandler);
        if (selectorProvider == null) {
            throw new NullPointerException("selectorProvider");
        }
        if (strategy == null) {
            throw new NullPointerException("selectStrategy");
        }
        provider = selectorProvider;
        final SelectorTuple selectorTuple = openSelector();
      	//创建选择器二元组(一个是原生selector,一个是包装过selector)
        selector = selectorTuple.selector;
        unwrappedSelector = selectorTuple.unwrappedSelector;
        selectStrategy = strategy;
    }
TAG3.2.1.1 newTaskQueue

创建NioEventLoop内的两个任务队列taskQueue

NioEventLoop
    private static Queue<Runnable> newTaskQueue(
            EventLoopTaskQueueFactory queueFactory) {
        if (queueFactory == null) {
          
            return newTaskQueue0(DEFAULT_MAX_PENDING_TASKS);
        }
        return queueFactory.newTaskQueue(DEFAULT_MAX_PENDING_TASKS);
    }

    private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) {
        // This event loop never calls takeTask()
      //创建taskQueue
        return maxPendingTasks == Integer.MAX_VALUE ? PlatformDependent.<Runnable>newMpscQueue()
                : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
    }
TAG3.2.1.2 SingleThreadEventLoop
 protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor,
                                    boolean addTaskWakesUp, Queue<Runnable> taskQueue, Queue<Runnable> tailTaskQueue,
                                    RejectedExecutionHandler rejectedExecutionHandler) {
//TAG3.2.1.2.1 
        super(parent, executor, addTaskWakesUp, taskQueue, rejectedExecutionHandler);
        tailTasks = ObjectUtil.checkNotNull(tailTaskQueue, "tailTaskQueue");
    }

传入两个任务队列,一个taskqueue,一个收尾队列tailTaskQueue------Queue taskQueue。队列内都是runnable类型对象。

TAG3.2.1.2.1 SingleThreadEventExecutor
    protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,
                                        boolean addTaskWakesUp, Queue<Runnable> taskQueue,
                                        RejectedExecutionHandler rejectedHandler) {
        super(parent);	//绑定当前nioeventloop的parent是EventExecutorGroup
        this.addTaskWakesUp = addTaskWakesUp;
        this.maxPendingTasks = DEFAULT_MAX_PENDING_EXECUTOR_TASKS;
      
//TAG3.2.1.2.1.1ThreadExecutorMap.apply(executor
      	//NioEventLoop内的executor的初始化
        this.executor = ThreadExecutorMap.apply(executor, this);//第一个参数为group内创建的executor,第二个参数是nioeventloop
        this.taskQueue = ObjectUtil.checkNotNull(taskQueue, "taskQueue");
        rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");
    }

		//绑定EventExecutorGroup为parent
    protected AbstractEventExecutor(EventExecutorGroup parent) {
        this.parent = parent;
    }
TAG3.2.1.2.1.1ThreadExecutorMap.apply(executor----nioEventLoop内executor初始化

这里负责nioeventloop内executor的初始化(初始化,使用group内创建的executor)

ThreadExecutorMap
		//第一个参数为group内创建的executor,第二个参数是nioeventloop
    public static Executor apply(final Executor executor, final EventExecutor eventExecutor) {
        ObjectUtil.checkNotNull(executor, "executor");
        ObjectUtil.checkNotNull(eventExecutor, "eventExecutor");
        return new Executor() {
            @Override
            public void execute(final Runnable command) {
//APPLY1 apply(command, eventExecutor)
//APPLY2 executor.execute
              	//调用group内的executor.execute;
                executor.execute(apply(command, eventExecutor));//第二个参数为当前nioeventloop
            }
        };
    }
//APPLY1 apply(command, eventExecutor)

包装command为runnable。

	//对command的包装类,在执行command.run前后,设置setCurrentEventExecutor为当前NioEventLoop
public static Runnable apply(final Runnable command, final EventExecutor eventExecutor) {
    ObjectUtil.checkNotNull(command, "command");
    ObjectUtil.checkNotNull(eventExecutor, "eventExecutor");
    return new Runnable() {
        @Override
        public void run() {
            setCurrentEventExecutor(eventExecutor);
            try {
                command.run();
            } finally {
                setCurrentEventExecutor(null);
            }
        }
    };
}
//APPLY2 executor.execute(ThreadPerTaskExecutor)
public final class ThreadPerTaskExecutor implements Executor {
    private final ThreadFactory threadFactory;

    public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
        if (threadFactory == null) {
            throw new NullPointerException("threadFactory");
        }
        this.threadFactory = threadFactory;
    }

    @Override
    public void execute(Runnable command) {
      	//使用线程工厂类,创建线程并开启
        threadFactory.newThread(command).start();
    }
}

image-20221202091200837

NioEventLoop内的属性包括parent(所属的group组)、executor对象(为group中创建的ThreadPerTaskExecutor)、两个队列(一个任务队列、一个收尾队列)。

此时,NioEventLoopGroup初始化过程结束,画个图,复盘一下创建流程。

A17CFF0F-8F70-4F09-9F5A-3D98417B8EFB_1_105_c
posted @ 2023-03-10 17:25  LeasonXue  阅读(45)  评论(0)    收藏  举报