netty:为什么 write() 必须在分配给通道的 Eventloop 线程中执行?
netty: why write() must get executed in Eventloop thread assigned to the channel?
应用程序在渠道之间交换数据是很常见的。
例如,对于代理服务器,每个入站连接都将与一个出站连接相关联,并在它们之间交换数据。在这种情况下,我知道我可以构建一个客户端 BootStrap
并执行 b.group(inboundChannel.eventLoop());
。然后两个通道可以在同一个线程中处理。
但是入站通道之间的数据交换呢?聊天室就是典型案例。耦合是任意的,对于恰好具有不同 EventLoop
线程的两个通道,它们将付出不必要的上下文切换开销。
所以我很困惑为什么存在这样的规则?如果写入可以非阻塞地完成(OS 套接字缓冲区有空闲 space 或对等方快速消耗,我们是否可以将数据写入 Channel
套接字(可能带有锁定)在任何调用线程中,如果它会阻塞,我们就可以触发 EventLoop
线程将写入位注册到选择器?
它只是在 Netty 中完成的一个设计选择,它还简化了自定义 ChannelHandler
s 的编写。通过总是调度到 EventLoop
入站和出站处理程序在执行这些处理程序时具有相同的语义,因此用户基本上可以将其处理程序编写为 "single-threaded"。
因为这是在 netty 的 "core" 中,所以无法更改。
应用程序在渠道之间交换数据是很常见的。
例如,对于代理服务器,每个入站连接都将与一个出站连接相关联,并在它们之间交换数据。在这种情况下,我知道我可以构建一个客户端 BootStrap
并执行 b.group(inboundChannel.eventLoop());
。然后两个通道可以在同一个线程中处理。
但是入站通道之间的数据交换呢?聊天室就是典型案例。耦合是任意的,对于恰好具有不同 EventLoop
线程的两个通道,它们将付出不必要的上下文切换开销。
所以我很困惑为什么存在这样的规则?如果写入可以非阻塞地完成(OS 套接字缓冲区有空闲 space 或对等方快速消耗,我们是否可以将数据写入 Channel
套接字(可能带有锁定)在任何调用线程中,如果它会阻塞,我们就可以触发 EventLoop
线程将写入位注册到选择器?
它只是在 Netty 中完成的一个设计选择,它还简化了自定义 ChannelHandler
s 的编写。通过总是调度到 EventLoop
入站和出站处理程序在执行这些处理程序时具有相同的语义,因此用户基本上可以将其处理程序编写为 "single-threaded"。
因为这是在 netty 的 "core" 中,所以无法更改。