"丢失"的UDP数据包(JBoss + DatagramSocket)

omn*_*nom 5 java udp datagram

我开发了一些基于JBoss + EJB的企业应用程序的一部分.我的模块需要处理大量传入的UDP数据包.我已经完成了一些负载测试,看起来如果以11ms的间隔发送数据包,一切都很好,但是在10ms间隔的情况下,一些数据包会丢失.在我看来这是相当奇怪的,但我做了10/11ms间隔负载测试比较几次,它总是相同的结果(10毫秒 - 一些"丢失"数据包,11毫秒 - 一切都很好).

如果同步出现问题,我希望在11ms测试(至少丢失一个数据包,或者至少有一个错误的计数器值)的情况下也可以看到它.因此,如果不是因为同步,那么我接收数据包的DatagramSocket可能无法正常工作.

我发现接收缓冲区大小(SO_RCVBUF)具有默认的57344值(可能是它的底层IO网络缓冲区依赖).我怀疑,也许当这个缓冲区满了,然后新的传入UDP数据报被拒绝.我尝试将此值设置为更高,但我注意到,如果我夸大,缓冲区将返回其默认大小.如果它的底层依赖,我如何从JBoss级别找出某个OS /网卡的最大缓冲区大小?

是否可能是由接收缓冲区大小引起的,或者57344值是否足以处理大多数情况?你对这些问题有经验吗?

我的DatagramSocket上没有设置超时.我的UDP数据报包含大约70个字节的数据(不包含数据报头的值).

[已编辑] 我必须使用UDP,因为我收到了Cisco Netflow数据 - 它是网络设备用来发送一些流量统计信息的协议.另外,我对发送的字节格式没有影响(例如,我不能为数据包添加计数器等).预计不会处理所有数据包(某些数据报可能会丢失),但我希望我将处理大部分数据包.在10ms间隔测试期间,大约30%的数据包丢失.

慢速处理不太可能导致此问题.目前,singleton组件在循环中保持对DatagramSocket调用receive方法的引用.收到数据包时,会将其传递给队列,并通过从池无状态组件中选择进行处理."Facade"Singleton仅负责接收数据包并将其传递给处理(它不等待处理完成事件).

提前谢谢,Piotr

Jef*_*rey 5

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

如果您需要保证交付,则应使用TCP.

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


Len*_*ate 3

UDP本质上是不可靠的。

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

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

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

总而言之,UDP 就是这样。