我正在实现TCP / IP之上的二进制协议,并使用Netty来实现这一目标。我的问题是性能相当差(600 msg / s)。我作为客户端连接到只有一个连接的服务器。当我用JTop研究运行实例时,我看到Netty非常大量地使用1个工作线程,而其他5个工作线程什么也没做(0%ussage)。我在网上挖掘,我发现的只是提到了ExecutionHandler。但是,如果这6个工作线程足够,我为什么要使用它呢?或者我误解了Netty如何使用这些线程?
My 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);
感谢任何提示 Matous
答案 0 :(得分:2)
NIO,或者说非阻塞版本的NIO(“新”I / O)允许您使用单个线程进行多个连接,因为线程不会阻塞(因此名称)读/写操作。阻塞I / O需要为每个连接提供一个线程,因为阻塞会阻止您处理不同连接之间的流量。
这使您可以执行更有效的通信,因为您不再需要一个线程开销。
提供了一个不错的教程here(最初的Oracle教程似乎已经从谷歌的脸上消失了。)
答案 1 :(得分:0)
您只看到一个工作线程被使用的原因是您只与服务器建立了一个连接。如果您建立了多个连接,则会使用更多的工作线程。
如果每个连接的工作都适合并行化,那么你可以实现一个在内部使用线程的处理程序,但是Netty不会为你做那个。
至于NIO / OIO的区别,NIO的想法是让一个线程处理多个连接的事件。但是,这并不意味着一个线程将处理所有工作。 “单线程”仅将工作分派给其他(即工作者)线程。
以下是Netty doc的摘录:
线程如何工作a中有两种类型的线程 NioServerSocketChannelFactory;一个是老板线程,另一个是 工人线程。
Boss线程每个绑定的ServerSocketChannel都有自己的boss线程。 例如,如果您打开了两个服务器端口,例如80和443,那么就是 将有两个老板线程。 boss线程接受传入连接 直到端口未绑定。成功接受连接后, boss线程将接受的Channel传递给其中一个worker NioServerSocketChannelFactory管理的线程。
工作线程一个NioServerSocketChannelFactory可以有一个或多个 工人线程。工作线程执行非阻塞读写 对于非阻塞模式下的一个或多个频道。