我有一个第三方组件,它试图在某种情况下向太多单独的地址发送太多UDP消息.这是在软件启动并且情况是暂时的时发生的突发.我实际上不确定这些消息的数量是多少还是每个消息都转到一个单独的IP地址.
无论如何,更改底层协议或有问题的组件不是一个选项,所以我正在寻找一种解决方法.StackTrace看起来像这样:
java.io.IOException: No buffer space available at java.net.PlainDatagramSocketImpl.send(Native Method) at java.net.DatagramSocket.send(DatagramSocket.java:612)
此问题(至少)发生在Java版本1.6.0_13和1.6.0_10以及Linux版本Ubuntu 9.04和RHEL 4.6上.
是否有任何Java系统属性或Linux配置调整可能有所帮助?
我终于确定了问题所在.Java IOException具有误导性,因为它是"没有可用的缓冲区空间",但根本问题是本地ARP表已被填充.在Linux上,默认的ARP表查找是1024(文件/ proc/sys/net/ipv4/neigh/default/gc_thresh1,/ proc/sys/net/ipv4/neigh/default/gc_thresh2,/ proc/sys/net/ipv4 /嘶/默认/ gc_thresh3).
在我的情况下(我假设您的情况)发生的事情是,您的Java代码是从与目标地址位于同一子网中的IP地址发送UDP数据包.在这种情况下,Linux计算机将执行ARP查找以将IP地址转换为硬件MAC地址.由于您正在将数据包发送到许多不同的IP,因此本地ARP表会快速填满,达到1024,这就是抛出Java异常的时候.
解决方案很简单,要么通过编辑前面提到的文件来增加限制,要么将服务器移动到与目标地址不同的子网中,这会导致Linux机箱不再执行邻居ARP查找(而是由网络上的路由器).