向大量客户端实时分发小消息的Netty选项



我正在设计一个(接近)实时的Netty服务器,以便在互联网上向大量客户端分发大量非常小的消息。在内部,尽可能快地进行测试,我发现我可以毫不费力地为1万个客户提供服务,但现在我们正试图通过互联网,在互联网上,延迟、带宽等变化非常大,我们遇到了可怕的outOfMemory问题,即使有2 GB的RAM。

我尝试过各种解决方案(将插座堆栈大小设置得更小,设置高低水位线,取消太旧的东西),它们有一点帮助,但似乎只起到一点帮助。有什么好的方法可以优化Netty,以便在没有显著延迟的情况下发送大量的小消息?此外,大部分消息只包含一种消息,如果它没有到达,我并不特别在意。我会使用UDP,但因为我们不能控制客户端,所以这不是真正的可能。是否可以在不影响其他消息的情况下,仅为此类消息设置单独的超时?

如果您能提供任何见解,我们将不胜感激。

通常,如果看到outOfMemory,您可以使用线程转储工具来转储线程。或者使用jvirtualvm和jconsole之类的东西来找出哪个类没有获得GCed,并不断消耗你的记忆。2Gigs对于现在的64位机器来说并不算大。试着把这个数字调大到3或4G左右,看看你是否没有达到OOM。如果你发现你可以在局域网中轻松处理10k连接,试着在你的网络处理器中添加一个小延迟。检查发生了什么。

您可能需要研究负载平衡方法。它用于使用硬件和软件在分布式系统中分配工作负载。适合您的系统的细节取决于几个因素,包括硬件升级等。当然,2GB的RAM对于服务器10k用户来说相当小,您需要提高这个限制。

您没有说明订阅流是恒定的还是突发的。您也没有说明客户端每秒是否必须支持最少的消息数。

鉴于我对Redis一无所知,以下任何一项都实用吗?

  • 对于您不关心的消息,如果channel.isWritable()==false,请立即丢弃。不幸的是,我不知道如何取消Netty发送缓冲区中的消息。无论如何,您都无法取消已传递到TCP发送缓冲区的消息,因此这并不是真正的依赖
  • 订阅的接收速度慢到最慢客户端的速率
  • 确定哪些客户端无法跟上(可能使用写入超时处理程序),并将它们移动到一个单独的订阅中,该订阅可以放慢速度。将已发布的消息复制到两个订阅
  • 你能把要发送给不同订阅的客户端的消息分开吗。如果客户无法及时取消订阅不重要的消息

如果随着时间的推移,您的平均发送速率高于客户端所能支持的速率,那么除了协商更改需求以降低最大允许吞吐量之外,没有其他解决方案了。

最新更新