我需要构建一个可以处理~10_000个请求/秒的UDP服务器。从下面的代码开始,测试java套接字是否可以处理这些请求。
我用~9000个请求轰炸服务器一分钟,
Total number of requests sent from the client : 596951
在tcp转储中我看到了
90640 packets captured
175182 packets received by filter
84542 packets dropped by kernel
UDP服务器代码:
try (DatagramSocket socket = new DatagramSocket(port)) {
System.out.println("Udp Server started at port :" + port);
while (true) {
byte[] buffer = new byte[1024];
DatagramPacket incomingDatagramPacket = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(incomingDatagramPacket);
LinkedTransferQueue.add(incomingDatagramPacket);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
} catch (SocketException e) {
e.printStackTrace();
}
内核在程序中丢弃数据包的可能原因是什么? 这个简单吗?
如何减少它?还有其他任何实现吗?
从这个link开始,从评论中读到,UDP协议的数据包丢失总是会发生在网络到java socket.recieve方法之间。
注意:必须弄清楚捕获的tcpdump数据包中是否存在异常,但丢弃了大量数据包。
tcpdump中的异常是lack of buffer space,为了知道收到的数据包数量,我使用的是iptraf-ng,它给出了每个端口收到的数据包数量:)< / em>的
答案 0 :(得分:2)
<强>辑阵线程强>
收到数据包后,您的代码示例不执行任何操作。如果是这种情况,多线程无法帮助您。
但是,如果仅用于测试并且您的实际应用程序需要对收到的数据包执行某些操作,则需要将数据包推送到另一个Thread
(或其中的一个池)并立即返回以侦听下一个包。
基本上,您需要尽量减少两次socket.receive()
。
注意:这是不这种情况下唯一可用的多线程模型。
缓冲区大小
使用映射到SO_RCVBUF的socket.setReceiveBufferSize
增加缓冲区大小:
增加SO_RCVBUF可能允许网络实现在数据包到达时比使用receive(DatagramPacket)接收更快地缓冲多个数据包。
但是,这只是提示:
SO_RCVBUF选项被网络实现用作提示来调整底层网络I / O缓冲区的大小。
如果您的设置允许,您也可以直接转到操作系统并更改缓冲区的大小。
<强>不相关强>
注意:仅在您不确定数据包大小小于1024字节时才读取此内容。
通用数据包的数据包缓冲区大小似乎很低,这可能导致错误,因为:如果数据包大于缓冲区,则不会出现错误,它将忽略溢出的字节。
编辑:
其他多线程模型
注意:这是一个想法,我不知道它是否真的有效。
3个主题:
初始化:
循环B1:
B2相同。
这是线程图(收到数据包的行):
B1 [--------|---] [--------|---]
B2 [--------|---] [--------|---]
答案 1 :(得分:0)
您可以使用AsynchronousDatagramChannel检查是否可以在此处使用NIO2 API,而不是使用线程。
帮助链接: https://www.ibm.com/developerworks/library/j-nio2-1/index.html
答案 2 :(得分:0)
可以处理的实际数据包数取决于您和目标服务器的CPU,它们与您的实际程序之间的网络连接。如果您需要一个高性能的Java网络解决方案,您可以使用珊瑚反应堆:http://www.coralblocks.com/index.php/the-simplicity-of-coralreactor/
答案 3 :(得分:0)
UDP的一个缺点是TCP没有提供可靠的传送保证 UDP协议的 mcast_recv_buf_size 和 ucast_recv_buf_size 配置属性用于指定接收缓冲区的数量。
它取决于您用来运行程序的操作系统。不同操作系统的缓冲区大小为:
<table sytle="width:100% border:1px solid black">
<tr>
<th><b>Operating System</b></th>
<th><b>Default Max UDP Buffer (in bytes)</b></th>
</tr>
<tr><td>Linux</td> <td>131071</td></tr>
<tr><td>Windows</td> <td>No known limit</td></tr>
<tr><td>Solaris</td> <td>262144</td></tr>
<tr><td>FreeBSD</td> <td>262144</td></tr>
<tr><td>AIX</td> <td>1048576</td></tr>
</table>
&#13;
因此UDP负载处理取决于机器和操作系统配置。