我们正在开发基于Netty的HTTP服务器,它接收Get请求,解码请求参数,进行一些webservice调用,然后在一些处理后返回结果
典型的请求通常在大约320毫秒内完成,其中200毫秒用于等待来自远程服务器的响应。
问题是我们无法在设置上产生高吞吐量。
这是一台配备30 GB RAM的16核机器。 CPU使用率从未超过20%,RAM udage永远不会超过5GB。 java堆大小设置为25GB
此外,我们更新了以下操作系统设置
ulimit =65000
net.core.somaxconn = 2048
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240 65535
这是一台ubuntu机器,我们正在使用Netty的3.2分支
我们在服务器上获得的最大吞吐量大约是每秒300个请求,随着每个后续测试最终降低到35 req / s,这个吞吐量也会下降。
我们在创建netty服务器引导程序时尝试使用FixThreadPool和cachedthreadpool。
无论我们做什么,性能数字都不会改变
我们的猜测是Netty没有创建足够的线程,因此队列中浪费了大量时间。
由于netty为我们提供了固定的并发性,是否存在我们遗漏的基本内容?
我们如何最大限度地利用CPU / RAM来从硬件中获得最大性能?
这是用于netty初始化的代码
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
//Executors.newFixedThreadPool(5000),5000));
// Configure the pipeline factory.
bootstrap.setPipelineFactory(this.nettyServerPipeline);
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("backlog",1000);
bootstrap.setOption("keepAlive", true);
bootstrap.setOption("connectTimeoutMillis", 10000);
bootstrap.setOption("client.reuseAddress", true);
// Bind and start to accept incoming connections.
bootstrap.bind(new InetSocketAddress(8099));
/* ServerBootstrap bootstrap =
new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newFixedThreadPool(1),
Executors.newFixedThreadPool(32)));
*/
我们尝试了多种上述设置的组合,但似乎没有什么能提高绝对吞吐量。
此致 SANKET
答案 0 :(得分:0)
您可能对可以打开的TCP连接数量设置了限制。这可能受到许多因素的限制。
如果您运行iptables(防火墙),则可能会达到跟踪的连接数量 - https://serverfault.com/questions/10852/what-limits-the-maximum-number-of-connections-on-a-linux-server
除了ulimit之外,您还可以尝试fs.file-max
。
net.ipv4.tcp_tw_reuse
设置也可能受到TIME_WAIT
中允许的TCP连接的持续时间的影响。尝试更改以下内容:
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_fin_timeout = 5
最后,可以为每个源+目标对创建的TCP连接数量有限制。因此,如果您的测试负载来自少量服务器,则可能会人为地限制您的服务器。
答案 1 :(得分:0)
根据在这个帖子上收到的建议,我们注意到我们正在调用memcached,这似乎阻止了工作线程
我们设法通过创建新的执行处理程序并将其传递给nettypipeline来解决问题
原始代码
ChannelPipeline pipeline =
new StaticChannelPipeline( new HttpRequestDecoder(), new HttpChunkAggregator(1048576),
requestDecoder, new HttpResponseEncoder(),
nettyServerHandler,filterHandler);
return pipeline;
新代码
ChannelPipeline pipeline = new StaticChannelPipeline( new HttpRequestDecoder(),
new HttpChunkAggregator(1048576),requestDecoder,
new HttpResponseEncoder(),nettyServerHandler,
executionHandler ,filterHandler);
return pipeline;
private final ExecutionHandler executionHandler = new ExecutionHandler(
//new MemoryAwareThreadPoolExecutor(6400,65536, 1048576,10,TimeUnit.MILLISECONDS));
这似乎解决了并发问题,但我们目前正在寻找修复一些已经出现的内存泄漏。