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

时间:2012-09-24 12:49:53

标签: java real-time netty out-of-memory

我正在设计一个(近)实时Netty服务器,以便将大量非常小的消息分发给互联网上的大量客户端。在内部,尽可能快地测试,我发现我可以做10k客户没有汗,但现在我们正试图穿越互联网,其中延迟,带宽等变化相当疯狂,我们遇到了可怕的outOfMemory问题,即使是2演出的RAM。

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

非常感谢您提供的任何见解。

3 个答案:

答案 0 :(得分:0)

通常,如果看到outOfMemory,您可以使用线程转储工具来转储线程。或者使用像jvirtualvm和jconsole这样的东西来找出哪些类没有得到GC并继续吃掉你的记忆。 对于现在的64位机器,2Gigs并不大。试着把这个数字变大到大约3或4G,看看你是不是打了OOM。 如果您发现可以在LAN中轻松处理10k连接,请尝试在netty处理程序中添加一个小延迟。检查发生了什么。

答案 1 :(得分:0)

您可能希望了解load balancing方法。它用于使用硬件和软件在分布式系统中分配工作负载。适用于您的系统的细节取决于几个因素,包括硬件升级等。当然,2GB的RAM对服务器10k用户来说相当小,您需要增加此限制。

答案 2 :(得分:0)

您没有说订阅流是常量还是突发。您也没有说客户端必须支持的最小消息数/秒。

鉴于我对Redis一无所知,以下是否有任何实用性?

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

如果您的平均发送速率高于客户端可以支持的时间,那么除了协商要求的变更以降低最大允许吞吐量之外,实际上没有其他解决方案。