美文网首页
浅谈 Netty 的 Reactor 线程模型

浅谈 Netty 的 Reactor 线程模型

作者: 爱打乒乓的程序员 | 来源:发表于2020-12-06 12:42 被阅读0次

    在聊 Netty 的 Reactor 线程模型之前,咱们需要对 Reactor 线程模型有一个基本的认识。

    【Wiki】The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.

    截取 wiki 上对 Reactor 线程模型的简述。通过简述可以得知以下几点:

    1. Reactor 线程模型是一个事件驱动模型(an event handling pattern)
    2. 可以并发处理一到多个输入源请求(by one or more inputs)
    3. 通过多路复用(demultiplexes)同步将请求分发到相关的事件处理器(associated request handlers)

    实际上,Reactor 线程模型在使用上有几种区别,分别为:

    • 单线程Reactor 线程模型
    • 多线程Reactor 线程模型
    • 主从Reactor 线程模型

    大神Doug Lee曾发表 Scalable IO in Java 论文,其中分别对上述的几种线程模型作出了解释,有兴趣的读者可以下载看看(强烈推荐!!!)

    那么在Netty中是使用哪种线程模型呢?实际上,在编写Netty服务器的时候,可以根据业务需求选择不同的线程模型。接下来通过代码模拟出各种场景下的使用。

    单线程 Reactor 线程模型

            NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(nioEventLoopGroup);
    

    这段是在编写Netty服务器创建线程组和启动ServerBootStrap并配置线程组的相关代码。这种使用场景无论是接收客户端请求或者处理请求都是在同一个线程内,弊端较为突出,当处理线程耗时长的话,Netty服务器是无法再接受新的请求,这在高并发的场景下是绝对不可取的!

    单线程Reactor线程模型

    多线程 Reactor 线程模型

            // 由一个线程接收客户端请求
            NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
            // 由8个线程处理客户端的
            NioEventLoopGroup workerGroup = new NioEventLoopGroup(8);
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup);
    

    这是经典的多线程Reactor线程模型的代码。其中,bossGroup线程池只设置为1,就代表只有一个线程接收客户端请求,而workerGroup线程池设置为8,则代表workerGroup线程池有8个线程处理客户端的请求。

    多线程Reactor线程模型

    多线程Reactor模型通过设置workerGroup线程池可以并发的处理客户端的请求,但是Acceptor却只有一个线程处理,会不会出现阻塞的情况呢?在高并发的场景下,会不会是一个性能瓶颈呢?如果在接收客户端的请求的时候,需要对请求做一些鉴权、认证等操作,那就更进一步影响接收客户端请求的效率。因此就“变形”延伸出——主从 Reactor 线程模型。

    主从 Reactor 线程模型

            // 有8个线程组成的线程池,专门接收客户端的请求
            NioEventLoopGroup bossGroup = new NioEventLoopGroup(8);
            // 有32个线程组成的线程池,专门处理客户端的请求
            NioEventLoopGroup workerGroup = new NioEventLoopGroup(32);
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup);
    

    其实通过代码可以发现,主从 Reactor 模型和多线程 Reactor 模型十分相似,只不过由原来的单线程 Acceptor 改为多线程而已,但在高并发的场景下,将会提高接口的QPS。

    主从Reactor线程模型

    如果觉得文章不错的话,麻烦点个赞哈,你的鼓励就是我的动力!对于文章有哪里不清楚或者有误的地方,欢迎在评论区留言~

    参考资料:

    【Wiki】https://en.wikipedia.org/wiki/Reactor_pattern

    【Doug Lee】Scalable IO in Java

    相关文章

      网友评论

          本文标题:浅谈 Netty 的 Reactor 线程模型

          本文链接:https://www.haomeiwen.com/subject/ajrowktx.html