从 Channel 引导客户端
你当然可以创建一个新的 Bootstrap 并使用它如9.2.1节所述,这个解决方案不一定有效。至少,你需要创建另一个 EventLoop 给新客户端 Channel 的,并且 Channel 将会需要在不同的 Thread 间进行上下文切换。
幸运的是,由于 EventLoop 继承自 EventLoopGroup ,您可以通过传递 接收到的 Channel 的 EventLoop 到 Bootstrap 的 group() 方法。这允许客户端 Channel 来操作 相同的 EventLoop,这样就能消除了额外的线程创建和所有相关的上下文切换的开销。
当你分享一个 EventLoop ,你保证所有 Channel 分配给 EventLoop 将使用相同的线程,消除上下文切换和相关的开销。(请记住,一个EventLoop分配给一个线程执行操作。)
共享一个 EventLoop 描述如下:
- 当 bind() 调用时,ServerBootstrap 创建一个新的ServerChannel 。 当绑定成功后,这个管道就能接收子管道了
- ServerChannel 接收新连接并且创建子管道来服务它们
- Channel 用于接收到的连接
- 管道自己创建了 Bootstrap,用于当 connect() 调用时创建一个新的管道
- 新管道连接到远端
Figure 9.4 EventLoop shared between channels with ServerBootstrap and Bootstrap
实现 EventLoop 共享,包括设置 EventLoop 引导通过Bootstrap.eventLoop() 方法。这是清单9.5所示。
- 创建一个新的 ServerBootstrap 来创建新的 SocketChannel 管道并且绑定他们
- 指定 EventLoopGroups 从 ServerChannel 和接收到的管道来注册并获取 EventLoops
- 指定 Channel 类来使用
- 设置处理器用于处理接收到的管道的 I/O 和数据
- 创建一个新的 Bootstrap 来连接到远程主机
- 设置处理器来处理 I/O
- 使用相同的 EventLoop 作为分配到接收的管道
- 连接到远端
- 连接完成处理业务逻辑 (比如, proxy)
- 通过配置了的 Bootstrap 来绑定到管道