java - 剖析 Netty 性能

标签 java linux netty

我正在编写一个 Netty 应用程序。该应用程序运行在 64 位八核 linux 机器上

Netty 应用程序是一个简单的路由器,它接受请求(传入管道),从请求中读取一些元数据并将数据转发到远程服务(传出管道)。

此远程服务将向传出管道返回一个或多个响应。 Netty 应用程序会将响应路由回原始客户端(传入管道)

将有成千上万的客户。将有数以千计的远程服务。

我正在进行一些小规模测试(10 个客户端,10 个远程服务),但我没有看到我期望的 99.9 百分位数下的 10 毫秒以下性能。我正在测量客户端和服务器端的延迟。

我正在使用类似于 SPDY 的完全异步协议(protocol)。当我们处理 FrameDecoder 中的第一个字节时,我会捕获时间(我只使用 System.nanoTime())。我在调用 channel.write() 之前停止了计时器。我正在测量从传入管道到传出管道的亚毫秒时间(99.9 个百分点),反之亦然。

我还测量了从 FrameDecoder 中的第一个字节到在(上面的)message.write() 上调用 ChannelFutureListener 回调的时间。时间高达几十毫秒(99.9 个百分点),但我无法说服自己这是有用的数据。

我最初的想法是我们有一些速度慢的客户端。我观看了 channel.isWritable() 并在返回 false 时进行了记录。该方法正常情况下不返回false

一些事实:

  • 我们正在使用 NIO 工厂。我们没有定制 worker 尺寸
  • 我们已禁用 Nagel (tcpNoDelay=true)
  • 我们启用了保持 Activity 状态 (keepAlive=true)
  • 90% 以上的时间 CPU 处于空闲状态
  • 网络空闲
  • GC (CMS) 在很短的时间内每 100 秒左右调用一次

是否有一种调试技术可以用来确定为什么我的 Netty 应用程序没有像我认为的那样快速运行?

感觉 channel.write() 将消息添加到队列中,而我们(使用 Netty 的应用程序开发人员)对这个队列没有透明度。不知道这个队列是Netty队列,OS队列,网卡队列还是什么。无论如何,我正在审查现有应用程序的示例,但我没有看到我遵循的任何反模式

感谢任何帮助/见解

最佳答案

Netty 默认创建 Runtime.getRuntime().availableProcessors() * 2 个 worker。在你的情况下是 16。这意味着您最多可以同时处理 16 个 channel ,其他 channel 将等到您释放 ChannelUpstreamHandler.handleUpstream/SimpleChannelHandler.messageReceived 处理程序,所以不要在这些 (IO) 线程中进行大量操作,否则您可能会卡住其他 channel 。

关于java - 剖析 Netty 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14613615/

相关文章:

linux - 在专用服务器上安装Windows Server

java - 如何在其他类中读取netty中的消息

Java Netty 3.3.1.Final,DynamicChannelBuffer.java :75, 无限循环,一个错误?

java - 访问静态变量

java - 如何将 Java 桌面应用程序连接到在线 mysql 数据库?

c++ - 记事本显示 Unicode 字符,因为文件是 ANSI?

c - execvp() 和/或 strings 出现问题,为什么此代码不起作用?

java - 如何在 Joda-Time 中仅解析带时区的日期?

java - 调用对应的 set 方法时获取对象值

java - Netty 示例中 ctx.read() 与 ctx.channel.read() 的使用