我开发了一些基于 JBoss+EJB 的企业应用程序的一部分。我的模块需要处理大量传入的 UDP 数据包。我已经做了一些负载测试,看起来如果以 11ms 的间隔发送数据包,一切都很好,但是在 10ms 的间隔的情况下,一些数据包会丢失。在我看来这很奇怪,但我多次进行了 10/11ms 间隔负载测试比较,结果总是相同(10ms - 一些“丢失”的数据包,11ms - 一切都很好)。
如果同步有问题,我希望它在 11 毫秒测试(至少一个数据包丢失,或至少一个错误的计数器值)的情况下也是可见的。因此,如果不是因为同步,那么我接收数据包的 DatagramSocket 可能无法按预期工作。
我发现接收缓冲区大小(SO_RCVBUF)具有默认值 57344(可能它依赖于底层 IO 网络缓冲区)。我怀疑,也许当这个缓冲区已满时,新传入的 UDP 数据报会被拒绝。我尝试将此值设置为更高,但我注意到如果我夸大其词,缓冲区将返回到其默认大小。如果它依赖于底层,我如何从 JBoss 级别找出某些操作系统/网卡的最大缓冲区大小?
是否可能是由接收缓冲区大小引起的,或者 57344 值可能足以处理大多数情况?您对此类问题有任何经验吗?
我的 DatagramSocket 上没有设置超时。我的 UDP 数据报包含大约 70 个字节的数据(不包括数据报头的值)。
[已编辑] 我必须使用 UDP,因为我收到 Cisco Netflow 数据 - 它是网络设备用来发送一些流量统计数据的协议。此外,我对发送的字节格式没有影响(例如,我不能为数据包添加计数器等)。预计不会处理所有数据包(一些数据报可能会丢失),但我希望我会处理大部分数据包。在 10 毫秒间隔测试期间,大约 30% 的数据包丢失。
缓慢的处理不太可能导致此问题。目前单例组件在循环中保存对 DatagramSocket 调用接收方法的引用。收到数据包后,将其传递到队列中,并由从池中选择的无状态组件进行处理。“门面”Singleton 只负责接收数据包并将其传递给处理(它不会等待处理完成事件)。
提前致谢, 皮奥特