我正在编写一个Netty应用程序。该应用程序在一台64位八核Linux服务器上运行。
Netty应用程序是一个简单的路由器,它接受请求(传入管道),从请求中读取一些元数据并将数据转发到远程服务(传出管道)。
此远程服务将向传出管道返回一个或多个响应。 Netty应用程序将把这些响应路由回源客户端(即传入管道)。
将有数千个客户端和数千个远程服务。
我正在进行一些小规模测试(十个客户端,十个远程服务),但在99.9百分位时,我没有看到期望的低于10毫秒的性能。我从客户端和服务器端测量延迟。
我使用了与SPDY类似的完全异步协议。当我们在FrameDecoder中处理第一个字节时,我捕获时间(我只是使用System.nanoTime())。在调用channel.write()之前,我停止计时器。我从传入管道到传出管道以及从传出管道到传入管道测量亚毫秒时间(99.9百分位)。
我还测量了从FrameDecoder中的第一个字节到(以上)message.write()上调用ChannelFutureListener回调的时间。时间是高十毫秒(99.9百分位),但我很难说服自己这是有用的数据。
我的最初想法是我们有一些慢客户端。我观察了channel.isWritable()并记录了当此方法返回false时的情况。在正常情况下,此方法不会返回false。
一些事实:
- 我们正在使用NIO工厂。我们没有自定义工作程序大小
- 我们已禁用Nagle(tcpNoDelay = true)
- 我们启用了保持活动(keepAlive = true)
- CPU 90%以上的时间处于空闲状态
- 网络处于空闲状态
- GC(CMS)每100秒左右被调用一次,时间非常短
是否有一种调试技术可以跟踪以确定为什么我的Netty应用程序运行速度不如我认为它应该?
感觉channel.write()将消息添加到队列中,但是我们(使用Netty的应用程序开发人员)无法透明地了解这个队列。我不知道这个队列是一个Netty队列、操作系统队列、网络卡队列还是其他什么队列。无论如何,我正在审查现有应用程序的示例,我没有看到我遵循的任何反模式。
感谢任何帮助/见解。