java UDP套接字可以处理多少个请求?
我需要建立一个UDP服务器,它可以处理〜10_000个请求/秒。从下面的代码开始,测试一个java套接字是否可以处理这些数量的请求。java UDP套接字可以处理多少个请求?
我轰击服务器在〜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();
}
内核在程序中丢弃数据包的可能原因是什么? m 这个简单吗?
如何减少?任何其他实现?
从这个link,从评论阅读,失去UDP协议到Java socket.recieve方法甚至网络之间可以随时发生的数据包。
注意:必须弄清楚捕获到的tcpdump数据包中的异常情况,但丢弃的数据包数量相当多。
了tcpdump的异常是lack of buffer space,为了知道数据包的数量收到,我现在用的是iptraf-ng这给每个端口:)
辑阵线程接收的数据包的数量
收到数据包后,您的代码示例不执行任何操作。如果是这样,多线程不能帮助你。但是,如果这仅仅用于测试,并且实际应用程序需要对接收到的数据包执行某些操作,则需要将数据包推送到另一个Thread
(或其中的一个池),然后立即返回以侦听下一个数据包。
基本上你需要最小化两次调用socket.receive()
之间的时间。
注意:这是而不是这种情况下唯一可用的多线程模型。
缓冲区大小
增加与socket.setReceiveBufferSize
缓冲区大小将映射到SO_RCVBUF:
增加SO_RCVBUF可以允许网络实现,以缓冲多个数据包时,包到达比正在接收更快使用receive(DatagramPacket)。
然而,这仅仅是一个暗示:
的SO_RCVBUF选项用于通过网络实现为暗示尺寸底层网络I/O缓冲区。
如果您的设置允许,也可以直接进入操作系统并更改缓冲区的大小。
无关
注:阅读本只有当你不能确定包的大小小于1024个字节。
对于通用数据包,您的数据包缓冲区大小似乎很低,这可能会导致错误,因为:如果数据包大于缓冲区,则不会有错误,它将忽略溢出字节。
编辑:
等多线程模型
注:这是一个想法,我不知道它的实际工作。
3个线程:
- 线程A:在处理分组
- 螺纹B1:接收分组
- 螺纹B2:接收分组
初始化:
- 原子计数器设置为0
- B1正在接收,B2正在等待。
虽然B1的环:
- 而计数器> 0等待
- 计数器+ = 1
- 接收的分组
- 计数器 - = 1
- 醒B2
- 将数据包推送到A队列
相同的B2。
这线程图(线在数据包已经收到):
B1 [--------|---] [--------|---]
B2 [--------|---] [--------|---]
而不是使用线程,您可以点击这里使用的API NIO2使用AsynchronousDatagramChannel的可能性。
帮助链接: https://www.ibm.com/developerworks/library/j-nio2-1/index.html
AsynchronousDatagramChannel类已从java中删除8 http://bugs.java.com/view_bug.do?bug_id=6993126 –
@ forum.test17这是不正确的,这不是bug报告所说的。它在Java 7发布之前已经从Java 7中撤销了,现在它已经存在于Java 8中了。请参阅Javadoc。 – EJP
包的实际数量有什么方法可以处理取决于你的服务器和目标服务器,它们和你的实际程序之间的网络连接的CPU。如果你需要在Java网络高性能的解决方案,你可以使用珊瑚反应器:http://www.coralblocks.com/index.php/the-simplicity-of-coralreactor/ 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> \t
<th><b>Default Max UDP Buffer (in bytes)</b></th>
</tr>
<tr><td>Linux</td> \t <td>131071</td></tr>
<tr><td>Windows</td> \t <td>No known limit</td></tr>
<tr><td>Solaris</td> \t <td>262144</td></tr>
<tr><td>FreeBSD</td> \t <td>262144</td></tr>
<tr><td>AIX</td> <td>1048576</td></tr>
</table>
所以UDP负载处理以及取决于机器的操作系统配置。
可能的原因是套接字接收缓冲区填满了,因为没有足够快地读取它。尝试减少'println()'调用,例如每百个数据报一个。 – EJP
@EJP我已经做到了,但仍然有丢包 –
使用多线程来同时处理多个数据包。您也可以在您的以太网接口和交换机上相应的端口上激活流量控制(但丢失数据包是一种被告知拥塞的方式,因此激活流量控制可能会产生不良的副作用)。 –