java – Linux机器上Netty 4.1的性能调优
我正在使用Netty 4.1 Beta3构建一个消息传递应用程序来设计我的服务器,并且服务器理解MQTT协议.
这是我的MqttServer.java类,它设置Netty服务器并将其绑定到特定端口. EventLoopGroup bossPool=new NioEventLoopGroup(); EventLoopGroup workerPool=new NioEventLoopGroup(); try { ServerBootstrap boot=new ServerBootstrap(); boot.group(bossPool,workerPool); boot.channel(NioServerSocketChannel.class); boot.childHandler(new MqttProxyChannel()); boot.bind(port).sync().channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); }finally { workerPool.shutdownGracefully(); bossPool.shutdownGracefully(); } } 现在,我在Mac上对我的应用程序进行了负载测试,具有以下配置 网络性能非常出色.在执行我的代码时我查看了jstack,发现netty NIO产生了大约19个线程,并且它们似乎都没有等待等待通道或其他东西. 然后我在linux机器上执行了我的代码 这是一款2核15GB机器.问题是我的MQTT客户端发送的数据包似乎需要很长时间才能通过netty管道,并且在获取jstack时我发现有5个netty线程,所有这些都被困在这个 ."nioEventLoopGroup-3-4" #112 prio=10 os_prio=0 tid=0x00007fb774008800 nid=0x2a0e runnable [0x00007fb768fec000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000006d0fdc898> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x00000006d100ae90> (a java.util.Collections$UnmodifiableSet) - locked <0x00000006d0fdc7f0> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:621) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:309) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:834) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) at java.lang.Thread.run(Thread.java:745) 这是一些与linux机器上的epoll相关的性能问题.如果是,则应对netty配置进行哪些更改以处理此问题或提高性能. 编辑 本地系统上的Java版本是: – java版“1.8.0_40” AWS上的Java版本是: – openjdk版“1.8.0_40-internal” 解决方法
使用工作线程来查看是否可以提高性能. NioEventLoopGroup()的标准构造函数创建默认的事件循环线程数量:
DEFAULT_EVENT_LOOP_THREADS = Math.max(1,SystemPropertyUtil.getInt( "io.netty.eventLoopThreads",Runtime.getRuntime().availableProcessors() * 2)); 如您所见,您可以将io.netty.eventLoopThreads作为启动参数传递,但我通常不这样做. 您还可以在NioEventLoopGroup()的构造函数中传递线程数. 在我们的环境中,我们拥有接受来自数百个客户端的通信的netty服务器.通常一个boss线程来处理连接就足够了.工作线程数量需要缩放.我们用这个: private final static int BOSS_THREADS = 1; private final static int MAX_WORKER_THREADS = 12; EventLoopGroup bossGroup = new NioEventLoopGroup(BOSS_THREADS); EventLoopGroup workerGroup = new NioEventLoopGroup(calculateThreadCount()); private int calculateThreadCount() { int threadCount; if ((threadCount = SystemPropertyUtil.getInt("io.netty.eventLoopThreads",0)) > 0) { return threadCount; } else { threadCount = Runtime.getRuntime().availableProcessors() * 2; return threadCount > MAX_WORKER_THREADS ? MAX_WORKER_THREADS : threadCount; } } 所以在我们的例子中我们只使用一个boss线程.工作线程取决于是否已发出启动参数.如果没有,那么使用核心* 2但不超过12. 您必须测试自己,尽管哪些数字最适合您的环境. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |