5

我开发了一些基于 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 只负责接收数据包并将其传递给处理(它不会等待处理完成事件)。

提前致谢, 皮奥特

4

4 回答 4

5

UDP 不保证传递,因此您可以调整参数,但不能保证消息会被传递,尤其是在非常大的数据传输的情况下。

如果你需要保证交付,你应该使用 TCP 来代替。

如果您需要(或想要)使用 UDP,您可以使用数字对每个数据包进行编码,并发送预期数量的数据包。例如,如果您发送了 10 个大数据包,您可以包含以下信息:数据包 1/10、数据包 2/10 等。这样您至少可以判断您是否没有收到所有数据包。如果您还没有收到它们,您可以发送请求以重新发送那些丢失的数据包。

于 2011-02-23T18:40:34.200 回答
3

UDP本质上是不可靠的。

数据报可以在发送者和接收者之间的任何点被丢弃,甚至在接收者中低于你的代码的级别。将 recv 缓冲区设置为更大的大小可能有助于机器内的网络代码缓冲更多数据报,但您应该预料到一些数据报无论如何都会丢失。

如果您的 recv 逻辑花费的时间太长(即比新数据报到达所需的时间长),那么您将永远落后,最终您将永远错过数据报。您所能做的就是确保您的 recv 代码尽可能快地运行,也许将入站数据报移动到队列并“稍后”或在另一个线程上处理它,但这只会将您的问题转移到您有一个不断增长的队列。

[重新编辑...] 什么正在处理您的队列以及生产者和消费者之间的锁定如何工作?更改您的代码,以便 recv 逻辑简单地增加计数并丢弃数据并循环回来,看看您是否丢失了更少的数据报;无论哪种方式,UDP都是不可靠的,您将拥有被丢弃的数据报,您应该期待并处理它。担心它意味着你关注的是错误的问题;利用你得到的数据并假设你不会得到很多,然后即使网络拥塞并且你的大部分数据报被丢弃,你的程序也能正常工作。

总之,这就是 UDP 的情况。

于 2011-02-23T19:03:12.550 回答
2

在您的测试中,缓冲区中最多只能有两个数据包,因此如果每个数据包小于 28KB,这应该没问题。

如您所知,UDP 是有损的,但您应该能够每 10 毫秒发送多个数据包。我建议你编写一个简单的接收器,它只监听数据包以确定它是你的应用程序还是网络/操作系统级别的东西。(我怀疑是后者)

于 2011-02-23T18:41:36.347 回答
1

我不知道 Java,但是……API 是否允许您为数据报调用异步侦听/接收:

  • 使用 O/S API 进行接收(将应用程序级缓冲区作为参数传递)
  • (等等,没有什么可以接收的......)
  • (O/S 从网络接收一些东西......)
  • O/S 将接收到的数据包放入缓冲区并完成/返回您的 API 调用

如果这是真的,那么我建议您执行几个并发的 API 调用实例,以便有几个并发的应用程序级缓冲区可以接收多个数据包。

于 2011-02-23T18:47:14.017 回答