我正在以10Mbps的速率接收UDP数据包。每个包由大约1109字节组成。
因此,它使我在eth0上收到的数据超过1pkt / ms。 C中的recvfrom()
接收数据包并将该数据包传递给Java。 Java对数据包进行过滤并进行必要的处理。
瓶颈是:recvfrom()
太慢:获取时间可能超过10毫秒,因为它没有获取CPU。
数据包通过接口(JNI)从C传递到Java需要1-2毫秒。
Java本身对数据包的处理需要0.5到1秒,具体取决于是否需要完成数据库插入或图像处理。
因此,问题在于许多延迟加起来,并且一半以上的数据包丢失。
可能的解决方案可能是:
完全排除对C的recvfrom()
的需求,并直接在Java中实现UDP提取(注意:首先,实现C的recvfrom()的目的是接收原始数据包,而不是UDP)。该解决方案可以减少JNI传输延迟。
在Java中的UDP接收功能上实现多线程。但是随后在UDP数据包中必须为该序列指定一个ID,因为在多线程处理中,无法保证输入数据包的顺序。 (但是,在此特定程序中,需要对数据包进行排序)。该解决方案在接收所有数据包方面可能会有所帮助,但是发送数据的协议需要修改以添加序列标识符。由于具有多线程,接收方可能有更高的机会获得CPU,并且可以快速获取数据包。
在Java中,阻塞队列可以实现为存储传入数据包的巨大缓冲区。然后,Java解析器可以使用来自此队列的数据包来处理它。但是,不确定接收器功能是否足够快并且是否将所有接收到的数据包放入队列而不丢弃任何数据包。
我想知道哪种解决方案可能是最佳的,或者将上述解决方案结合使用即可。任何帮助或建议,将不胜感激。
最佳答案
这种爆发持续多长时间?它是连续的,并且会永远持续下去吗?然后,您需要功能更强大的硬件来处理负载。可能是一些负载平衡,其中多个服务器处理传入的数据。
爆发只会持续很短的时间,最多像一两秒吗?然后,让较低的级别尽可能快地读取所有数据包,并将其放入队列中,然后让较高的级别在自己的时间内从队列中获取消息。