Java 不稳定的表现
我正在写一份棘手的申请书。该应用程序运行在64位八核linux机器上 Netty应用程序是一个简单的路由器,它接受请求(传入管道),从请求中读取一些元数据,并将数据转发给远程服务(传出管道) 此远程服务将向传出管道返回一个或多个响应。Netty应用程序将把响应路由回发起客户端(传入管道) 将会有成千上万的客户。将有成千上万的远程服务 我正在做一些小规模的测试(十个客户端,十个远程服务),但我没有看到99.9%的预期性能低于10毫秒。我从客户端和服务器端测量延迟 我使用的是与SPDY类似的完全异步协议。我捕获处理帧解码器中的第一个字节时的时间(我只使用System.nanoTime()。我在调用channel.write()之前停止了计时器。我正在测量从输入管道到输出管道的亚毫秒时间(99.9个百分点),反之亦然 我还测量了从FrameDecoder中的第一个字节到对(上述)message.write()调用ChannelFutureListener回调的时间。这个时间高达几十毫秒(99.9%),但我很难说服自己这是有用的数据 我最初的想法是我们有一些慢客户。我观看了channel.isWritable()并在返回false时进行了记录。在正常情况下,此方法不会返回false 一些事实:Java 不稳定的表现,java,linux,netty,Java,Linux,Netty,我正在写一份棘手的申请书。该应用程序运行在64位八核linux机器上 Netty应用程序是一个简单的路由器,它接受请求(传入管道),从请求中读取一些元数据,并将数据转发给远程服务(传出管道) 此远程服务将向传出管道返回一个或多个响应。Netty应用程序将把响应路由回发起客户端(传入管道) 将会有成千上万的客户。将有成千上万的远程服务 我正在做一些小规模的测试(十个客户端,十个远程服务),但我没有看到99.9%的预期性能低于10毫秒。我从客户端和服务器端测量延迟 我使用的是与SPDY类似的完全异步
- 我们正在使用NIO工厂。我们还没有定制工人的尺寸
- 我们已禁用Nagel(tcpNoDelay=true)
- 我们已启用保持活动(keepAlive=true)
- CPU 90%以上的时间处于空闲状态
- 网络空闲
- GC(CMS)在很短的时间内每隔100秒左右被调用一次
感谢您的帮助/洞察Netty创建Runtime.getRuntime().availableProcessors()*默认情况下有2个工作进程。你的情况是16。这意味着您最多可以同时处理16个通道,其他通道将等待您释放ChannelUpstreamHandler.handleUpstream/SimpleChannelHandler.messageReceived处理程序,因此不要在这些(IO)线程中执行繁重的操作,否则您可能会卡住其他通道。您尚未指定Netty版本,但听起来像是内蒂3。 Netty 4现在稳定了,我建议您尽快更新它。 您已经指定需要超低延迟时间,以及数以万计的客户端和服务。这东西不太合身。与OIO相比,NIO本质上是潜在的。然而,这里的陷阱是OIO可能无法达到您希望的客户数量。尽管如此,我还是会使用OIO事件循环/工厂,看看它是如何运行的
我自己有一个TCP服务器,在本地主机上发送、接收和处理几个TCP数据包(从客户端打开套接字到服务器关闭套接字的时间)大约需要30毫秒。如果你真的需要如此低的延迟,我建议你离开TCP,因为打开连接需要SYN/ACK垃圾邮件,这将占用你10ms的大部分时间。如果你使用System.nanoTime()等简单的东西,在多线程环境中测量时间是非常困难的。想象一下1核系统上的以下情况:
这允许您在操作系统不干扰的情况下测量操作的准确性能。,因为在上面的示例中,线程B也可以在程序之外。在这种情况下,一种常见的方法是对干扰进行中位数,这将为您提供代码速度的估计值。
但是,您可以假设,在其他空闲的多核系统上,将有另一个核来处理后台任务,因此您的测量通常不会中断。将此线程设置为高优先级也会有所帮助
一般建议:使用比内核更多的线程不是一个好主意,除非您知道这些线程经常会被某些操作阻塞。在IO操作中使用非阻塞NIO时,情况并非如此,因为没有阻塞 因此,在您的特殊情况下,您实际上会降低客户机的性能,如上所述,因为在高负载情况下,通信将有50%的时间处于暂停状态。在最坏的情况下,这可能会导致客户