【发布时间】:2011-02-23 18:34:36
【问题描述】:
我开发了一些基于 JBoss+EJB 的企业应用程序的一部分。我的模块需要处理大量传入的 UDP 数据包。我已经做了一些负载测试,看起来如果以 11ms 的间隔发送数据包,一切都很好,但是在 10ms 的间隔的情况下,一些数据包会丢失。在我看来这很奇怪,但我做了几次 10/11ms 间隔负载测试比较,结果总是相同(10 毫秒 - 一些“丢失”的数据包,11 毫秒 - 一切都很好)。
如果同步有问题,我希望它在 11 毫秒测试(至少丢失一个数据包,或至少一个错误的计数器值)的情况下也会可见。 因此,如果不是因为同步,那么我接收数据包的 DatagramSocket 可能无法按预期工作。
我发现接收缓冲区大小 (SO_RCVBUF) 的默认值为 57344(可能与底层 IO 网络缓冲区有关)。我怀疑,也许当这个缓冲区已满时,新传入的 UDP 数据报会被拒绝。我尝试将此值设置为更高,但我注意到如果我夸大其词,缓冲区将返回到其默认大小。如果它依赖于底层,我如何从 JBoss 级别找出某些操作系统/网卡的最大缓冲区大小?
这可能是由接收缓冲区大小引起的,还是 57344 值足以处理大多数情况?您对此类问题有任何经验吗?
我的 DatagramSocket 上没有设置超时。我的 UDP 数据报包含大约 70 个字节的数据(不包括数据报头的值)。
[已编辑] 我必须使用 UDP,因为我收到 Cisco Netflow 数据 - 它是网络设备用来发送一些流量统计数据的协议。另外,我对发送的字节格式没有影响(例如,我不能为数据包添加计数器等等)。预计不会处理所有数据包(一些数据报可能会丢失),但我希望我会处理大部分数据包。在 10 毫秒间隔测试期间,大约 30% 的数据包丢失。
缓慢的处理不太可能导致此问题。目前单例组件在循环中保存对 DatagramSocket 调用接收方法的引用。收到数据包后,将其传递到队列中,并由从池中选择的无状态组件进行处理。 “Facade” Singleton 只负责接收数据包并将其传递给处理(它不会等待处理完成事件)。
提前致谢, 彼得
【问题讨论】:
-
为什么需要 UDP?我会使用 TCP,直到您的分析表明需要转到 UDP 的饱和层。此外,我对 UDP 的经验是数据通常是重复的。 “这是目前的状态。”因此,如果您错过了这个数据包,请不要担心,因为很快就会有另一个数据包!
-
“缓慢的处理不太可能导致此问题。” --我认为是,因为 10 毫秒很小,与线程量子的持续时间大致相同。
-
这 10 毫秒可能因不同的操作系统/处理器而异。你可以减少发送数据的频率,比如 100 毫秒吗?
-
@ChrisW 也许你是对的,但如果是这样,在 11ms 间隔的情况下是否也应该看到数据包丢失? (我不能观察任何人)@Jeff Storey 它只取决于外部网络设备发送数据包的速度。我只负责接收和处理。