Reactor线程模型的对比
在高性能网络通信框架中,I/O 模型和线程模型是两个核心的关注点。对于 I/O 多路复用模型,需要将 selector 上的事件分发给对应的事件处理者。在 Reactor 线程模型中,Reactor 作为事件分发器,负责分发各种 I/O 事件。
一个 server 启动后,需要监听网络端口上的远程连接。
当有 client 请求建立连接时,selector 上会产生 accept 事件,Reactor 将 accept 事件交给 acceptor 处理,从而建立连接。
连接建立好后,server 和 client 之间就可以发送和接收数据了,数据的接收需要经过 decode 操作解析成所需的格式,然后 compute 进行业务逻辑处理,发送前需要 encode 成网络传输所需的格式。
整体流程为:accept -> 建立连接 -> read -> decode -> compute -> encode -> send
Reactor线程模型对比
单线程模型
所有的操作全部运行在一个 Reactor 线程中,一次只能接收和处理一个连接。
当一个请求未处理完时,selector 无法接收新的请求,也就无法建立新的连接,会造成请求超时。
即使每个请求的响应都很快,同时能够处理的请求数量也很有限。
多线程模型
多线程的改进在于将 decode、compute、encode 这些非 I/O 操作放到了线程池中进行处理,这样一来,业务逻辑的耗时长短不会对 Reactor 线程造成影响,Reactor 线程只需要负责处理 accept、read、send 等 I/O 操作即可。
主从多线程模型
在多线程模型中,Reactor 需要处理多种 I/O 操作,其中 read 和 send 操作可能因为数据量大导致耗时较长,这会影响其他事件的处理,从而影响并发度。
主从多线程模型中,Reactor 根据职责划分为 mainReactor 和 subReactor,其中 mainReactor 只负责分发 accept 事件给 acceptor 处理,acceptor 与 mainReactor 运行在同一个线程中,建立连接后交给 subReacotr 处理。subReactor 与多线程模型中的 Reactor 类似,它负责 read 和 send 操作,将 decode、compute和encode 操作放到业务线程池中处理。为了提高并发度,可以创建多个 subReactor,这样就可以充分利用多处理的能力。
netty中的实现
netty 中的 bossGroup 对应 Reactor 线程模型中的 mainReactor,workerGroup 对应 Reactor 线程模型中的 subReactor,可通过配置 bossGroup 和 workerGroup 参数指定线程模型。
单线程模型
1 | // 配置eventLoopGroup为单线程 |
多线程模型
1 | // 配置eventLoopGroup为单线程 |
主从多线程模型
1 | // 配置bossGroup |
- 2021-04-13
本文记录 java BIO 和 NIO 的使用方式,以方便查阅。
- 2021-08-12
在使用 netty 开发网络应用时,通常会设置
ChannelOption.SO_BACKLOG
,不知你有没想过这个参数的作用是什么。 - 2021-08-08
学习一门新的语言,通常是以 HelloWorld 开始的。类似地,学习一个网络框架,通常是以 EchoServer 开始的。接下来我们就来看下如何通过 netty 实现一个 EchoServer。
- 2021-04-14
Netty server 在启动过程中会触发一系列的 Inbound 事件,它的流程是怎样的呢?
- 2022-01-07
兴趣是最好的老师,当你对一件事情感兴趣的时候,你就更容易长久地坚持下去,从而达到一个更高的高度,或许还能够取得意想不到的效果。接下来我会从实现一个 echo server 开始 netty 的探索旅程,如果你也对 netty 感兴趣,那么我们就开始吧。