Netty Not Scaling for Higher concurrency

时间:2014-07-31 10:13:04

标签: multithreading performance concurrency netty nio

我们正在开发基于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

2 个答案:

答案 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));

这似乎解决了并发问题,但我们目前正在寻找修复一些已经出现的内存泄漏。