【问题标题】:Netty client uses only one threadNetty 客户端只使用一个线程
【发布时间】:2013-11-11 22:04:07
【问题描述】:

我在 TCP/IP 之上实现了一个二进制协议,并使用 Netty 来实现这一点。我的问题是性能相当差(600 msg/s)。我作为客户端连接到仅具有一个连接的服务器。当我使用 JTop 调查运行实例时,我看到 Netty 正在大量使用 1 个工作线程,而其他 5 个工作线程什么也没做(0% 使用率)。我在网上挖掘,我发现的只是提到了 ExecutionHandler。但是,如果这 6 个工作线程就足够了,我为什么要使用它。还是我误解了 Netty 是如何使用这些线程的?

我的 Netty 初始化代码:

this.channelFactory = new NioClientSocketChannelFactory(this.executors, DaemonExecutors.newCachedDaemonThreadPool(), 1, 6);
this.clientBootstrap = new ClientBootstrap(channelFactory);
this.channelGroupHandler = new ClientChannelGroupHandler(this.channels);
this.clientBootstrap.getPipeline().addLast("ChannelGroupHandler", this.channelGroupHandler);

感谢任何提示 马图斯

【问题讨论】:

  • 您是说您使用单个客户端连接到服务器吗?那么为什么服务器会使用其他线程,你知道每个客户端一个线程。
  • 我正在实现一个客户端,它现在只连接一个连接,将来会有更多。我认为使用 NIO 的全部意义在于一个连接可以由多个线程提供服务?
  • 你完全错了。 NIO 允许您使用单个线程来服务多个连接。
  • 啊哈,我从未真正深入了解 NIO,感谢您指出这一点。你有什么好的资源可供我阅读吗?关于线程?无论如何,这解释了我在 Netty 中看到的行为。谢谢!我能以某种方式接受 cmets 吗?

标签: java netty nio


【解决方案1】:

NIO,或者更确切地说是 NIO 的非阻塞版本(“新”I/O)允许您将单个线程用于多个连接,因为线程在读/写时不会阻塞(因此得名)操作。阻塞 I/O 需要每个连接都有一个线程,因为阻塞会阻止您处理不同连接之间的流量。

这使您可以执行更有效的通信,因为您不再需要线程开销。

here 提供了一个不错的教程(原来的 Oracle 教程似乎已经从 Google 面前消失了)。

【讨论】:

  • Netty确实只使用了一个boss线程,但它确实使用了多个worker线程来处理这些事件所需的工作。
  • 他只有一个连接。其他工作线程没有足够的工作。
  • 我有同样的设置。我只想要一个连接(一个客户端 - 一个 tcp 会话),但我不仅需要客户端发送消息,还需要从服务器接收消息。但是,当我调整服务器以同时发送多条消息时,只有其中两条到达客户端。我已确认消息已离开服务器(logging&wireshark)。任何想法为什么客户端线程只接受 2 条消息? #netty
【解决方案2】:

您只看到一个工作线程被使用的原因是因为您只与服务器建立了一个连接。如果你建立了多个连接,就会使用更多的工作线程。

如果每个连接的工作都适合并行化,那么您可以实现一个在内部使用线程的处理程序,但 Netty 不会为您这样做。

至于 NIO/OIO 的区别,确实 NIO 的想法是让一个线程处理多个连接的事件。然而,这并不意味着一个线程将处理所有的工作。 “单线程”仅将工作分派给其他(即工作线程)线程。

这是 Netty 文档的摘录:

线程如何工作 线程中有两种类型 NioServerSocketChannelFactory;一个是boss线程,另一个是 工作线程。

Boss 线程 每个绑定的ServerSocketChannel 都有自己的boss 线程。 例如,如果您打开了 80 和 443 等两个服务器端口,您 将有两个老板线程。老板线程接受传入的连接 直到端口未绑定。成功接受连接后, 老板线程将接受的频道传递给其中一名工人 NioServerSocketChannelFactory 管理的线程。

工作线程 一个 NioServerSocketChannelFactory 可以有一个或多个 工作线程。工作线程执行非阻塞读写 用于非阻塞模式的一个或多个通道。

【讨论】:

  • 感谢您的回复!从我在客户端看到的情况来看,一个工作线程处理我的连接的所有工作。一旦我调整我的服务器模拟器,我将使用更多连接进行一些实验,以便它能够接受一个以上的连接:)。但无论如何,来自客户端连接的流量似乎总是由同一个工作线程/线程处理(它不是分布式的)。未能在 Netty 文档中找到任何关于此的描述,但我对 Kayaman 指出的解释感到满意。当我有时间时会检查 Netty 代码以确认。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多