Netty-DefaultEventExecutor工作机制

   DefaultEventExecutor源码
   业务线程池优化策略
   Netty线程绑定机制原理


DefaultEventExecutor源码

     DefaultEventExecutor是JDK线程池ExecutorService的一种优化实现,继承关系图:
     在这里插入图片描述
     由于同时实现ScheduledExecutorService和ExecutorService接口,DefaultEventExecutor可以同时处理普通的Runnable和定时任务,它的run方法是从任务队列中循环获取Runnable并执行,代码如下(DefaultEventExecutor类):


protected void run() {
    do {
        Runnable task = this.takeTask();
        if (task != null) {
            task.run();
            this.updateLastExecutionTime();
        }
    } while(!this.confirmShutdown());
}

业务线程池优化策略

  1. 使用EventExecutorGroup绑定业务Handler
    在这里插入图片描述
    对于某个客户端连接Channel,只会注册到一个NioEventLoop线程中,用于处理网络I/O操作,业务的ChannelHandler指定了运行线程池EventExecutorGroup之后,创建ChannelHandlerContext上下文时会从EventExecutorGroup中选择一个EventExecutor绑定到该Channel对应的ChannelHandler实例。对于某个Channel,它的两侧都进行线程绑定,消息接收线程是NioEventLoop,业务逻辑处理在EventExecutor线程中,这样就实现了网络I/O线程与业务逻辑线程处理线程的绑定,对于某个TCP连接由于双方是一对一关系,所以降低了锁竞争。当客户端并发连接比较多时,会有N个Channel并行处理,这样既可以充分利用多核CPU的计算资源,又最大程度降低了锁竞争,提升了系统的并发处理性能。

     2.后台创建一个JDK线程池专门处理业务逻辑操作
     在这里插入图片描述
     当后端创建一个统一的业务逻辑处理线程池时,网络I/O处理线程NioEventLoop(多个)与业务线程池就会形成M对N的映射关系,由于JDK的ThreadPoolExecutor采用的是"一个阻塞队列+N个工作线程"模型,如果业务线程数比较多,就会形成激烈的锁竞争。


Netty线程绑定机制原理

     NioEventLoop线程与SocketChannel绑定关系的创建:当Netty服务器接受客户端TCP连接时,触发channelRead方法,由ServerBootstrapAcceptor负责将新接入的SocketChannel注册到NioEventLoop的Selector,同时建立SocketChannel和NioEventLoop的绑定关系(从NioEventGroup中选择一个NioEventLoop线程做SocketChannel的注册)。
     业务ChannelHandler异步执行的线程切换点发生在AbstractChannelHandlerContext的invokeChannelRead(final AbstractChannelHandlerContext next, Object msg)方法中,由Netty的NioEventLoop线程切换到业务ChannelHandler绑定的DefaultEventExecutor中

发布了16 篇原创文章 · 获赞 15 · 访问量 1046

猜你喜欢

转载自blog.csdn.net/MarchRS/article/details/104423221