我正在选择一个网络库来实现一个不能消耗任何微秒的客户端/服务器系统。它将实现自己的协议来发送和接收消息。我正在寻找一个好的NIO框架,这将允许我轻松开发服务器和客户端,而不必过多担心低级别的选择器细节。每个人都建议我使用Netty,但在向团队提交框架之前,我想尝试2或3个其他选择。我不太喜欢Netty的一件事是它如何使用自己的ByteBuf实现和引用计数来处理ByteBuffers。任何人都可以分享您的想法和替代方案吗?
答案 0 :(得分:27)
我们开发了一个NIO networking library,它在环回过程中执行不到2微秒,而不会为GC产生任何垃圾。正如Peter Lawrey所提到的,原生JDK选择器会产生大量垃圾,但我们通过实现自己的epoll选择器修复了所有这些垃圾泄漏。繁忙的等待选择器线程非常适合延迟,但必须保持平衡,不要烧坏芯片或消耗大量能量。我们的选择器实现使用低级技巧来实现一种节能模式来处理这种平衡。
除了CoralReactor之外,您还可以查看Grizzly和Mina,但我们还没有使用这些框架。
对于某些Netty TCP性能基准测试,您可以查看here。
答案 1 :(得分:16)
这假设你真的想要节省每一微秒。大多数应用程序没有这么严格的要求。
如果要保存微秒,则需要在专用cpus上使用忙等待非阻塞NIO。这不能很好地扩展,因为您需要拥有足够的CPU,但确实可以最大限度地减少处理IO的延迟。我建议您也绑定隔离的CPU以最小化抖动。
您将希望避免使用选择器,因为它们会阻止和/或创建相当多的垃圾添加到GC暂停。
另外,为了最大程度地减少延迟,您需要使用低延迟的内核旁路网络适配器,例如Solarflare。
您将需要使用推送解析器,以便在下载时解码/解析消息。即你不想等到收到整个邮件才开始。
组合使用这些技巧可以为每个请求或入站事件节省10 - 30微秒。
Netty是一种更好的可扩展性解决方案,即更高的净吞吐量,但延迟成本较低,大多数基于支持Web服务的框架都可以容忍毫秒延迟。
答案 2 :(得分:13)
如果您可以使用至少一些Scala,Spray是Netty的绝佳替代品。从长远来看,Play框架例如打算从Netty迁移到Spray。 Spray提供不同级别的TCP抽象。那些是:
您深入挖掘堆栈,传递的信息越原始。在块级API中,您非常接近原始字节缓冲区。我自己从未使用过这种低抽象级别,但我听到了很好的东西。
Spray构建于Akka IO之上,Akka IO再次构建于Java NIO之上。所有功能都围绕着Actor抽象,这使得使用Spray构建并行应用程序变得容易。我认为聊天服务器将是一个完美的用例。由于Akka提供了Java API,因此您应该能够使用主要使用此API的Spray。但是,您可能需要不时地阅读一些Scala源代码。最终,Spray将完全融入Akka。
编辑:引用Spray网站:" Spray不再维护,已被Akka HTTP取代。 Playframework从Play 2.4.X开始实验性地支持Akka HTTP Server后端。在Play 2.6.X版本中,播放完全迁移到Akka HTTP服务器后端。