如何通过Netty允许更多的并发客户端连接?

7

首先,感谢Netty的所有贡献者为这个杰出的库做出的贡献。我已经愉快地使用它几周了。

最近,我开始对我的系统进行负载测试,但是现在我正在使用Netty时遇到一些可扩展性问题。我尝试分叉尽可能多的同时Netty客户端连接到一个Netty服务器。对于少量客户端(<50),系统运行良好。然而,对于大量客户端(>100),我发现客户端端总是提示“ClosedChannelException”:

java.nio.channels.ClosedChannelException at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$1.operationComplete(NioClientSocketPipelineSink.java:157) at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:381) at org.jboss.netty.channel.DefaultChannelFuture.notifyListeners(DefaultChannelFuture.java:367) at org.jboss.netty.channel.DefaultChannelFuture.setSuccess(DefaultChannelFuture.java:316) at org.jboss.netty.channel.AbstractChannel$ChannelCloseFuture.setClosed(AbstractChannel.java:351) at org.jboss.netty.channel.AbstractChannel.setClosed(AbstractChannel.java:188) at org.jboss.netty.channel.socket.nio.NioSocketChannel.setClosed(NioSocketChannel.java:146) at org.jboss.netty.channel.socket.nio.NioWorker.close(NioWorker.java:592) at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.close(NioClientSocketPipelineSink.java:415) at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.processConnectTimeout(NioClientSocketPipelineSink.java:379) at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.run(NioClientSocketPipelineSink.java:299) at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:44) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722)

我想知道如何使Netty支持更多的同时客户端连接,例如10K。我正在使用最新版本的Netty。以下是测试场景:

每个客户端向服务器发送一个四字母字符串,服务器处理程序在接收到字符串后不执行任何操作。服务器和客户端都运行在具备8个核心和16GB内存的高性能机器上。两台机器通过千兆网络连接。

你有什么提示吗?


我在堆栈跟踪中看到了“.processConnectTimeout”,客户端超时的原因是什么? - Abe
也许客户端的主线程负载过重?我不是完全确定。但在采纳Jestan的建议3)后,这个问题消失了。 - Jeff Huang
1个回答

7

1) 您可以在客户端引导程序中调整connectTimeout,以确保没有网络/服务器问题。

clientBootStrap.setOption("connectTimeoutMillis", optimumTimout);

2) 通过在Netty服务器中设置backlog值,您可以增加传入连接队列的大小,从而客户端将更有可能连接到服务器。

serverBootStrap.setOption("backlog", 1000);

3) 您已经说过您的应用程序在同时创建许多连接,如果应用程序连接过快,则客户端Boss线程可能会滞后

Netty 3.2.7 Final允许在NioClientSocketChannelFactory构造函数中设置多个客户端Boss线程以避免此问题。


1
谢谢Jestan。您的观点很有帮助。事实上,是因为客户端连接得太快了。降低客户端线程分叉速度后,现在Netty可以轻松支持10K并发客户端而不会抛出任何异常。 - Jeff Huang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接