我需要构建一个可以处理 ~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();
}
What is the the probable cause kernel dropping the packets in program this simple ?
How to reduce it ? Any other implementation ?
从这里link ,从评论中读到,即使在网络与 java socket.recieve 方法之间,UDP 协议(protocol)的数据包丢失也总是会发生。
注意:抓到的tcpdump包有异常要搞清楚,但是掉包的数量还是挺多的。
tcpdump 中的异常是 lack of buffer space ,为了知道收到的数据包数量,我使用了 iptraf-ng它给出了每个端口接收到的数据包数量:)
最佳答案
多线程
您的代码示例在收到数据包后不执行任何操作。如果是这样,多线程就帮不了你了。
然而,如果这只是为了测试,而您的实际应用程序需要对接收到的数据包做一些事情,您需要将数据包推送到另一个 Thread
(或它们的池)并立即返回监听下一个数据包。
基本上,您需要最小化 socket.receive()
的两次调用之间的时间。
注意:这不是可用于这种情况的唯一多线程模型。
缓冲区大小
使用映射到 SO_RCVBUF 的 socket.setReceiveBufferSize
增加缓冲区大小:
Increasing SO_RCVBUF may allow the network implementation to buffer multiple packets when packets arrive faster than are being received using receive(DatagramPacket).
然而,这只是一个提示:
The SO_RCVBUF option is used by the the network implementation as a hint to size the underlying network I/O buffers.
如果您的设置允许,您也可以直接转到操作系统并更改缓冲区的大小。
不相关
注意:仅当您不确定数据包大小是否小于 1024 字节时才阅读此内容。
对于通用数据包,您的数据包缓冲区大小似乎较小,这可能会导致错误,因为:如果数据包大于您的缓冲区,则不会出现错误,它只会忽略溢出的字节。
编辑:
其他多线程模型
注:这是一个想法,不知道是否真的可行。
3 个线程:
- 线程A:处理数据包
- 线程B1:接收数据包
- 线程B2:接收数据包
初始化:
- 原子计数器设置为 0
- B1 正在接收,B2 正在等待。
B1 的 While 循环:
- while 计数器 > 0 等待
- 计数器 += 1
- 收到包裹
- 计数器 -= 1
- 唤醒B2
- 将数据包推送到A的队列
B2 也一样。
这是线程图(已收到数据包的行):
B1 [--------|---] [--------|---]
B2 [--------|---] [--------|---]
关于java - 一个 java UDP 套接字可以处理多少个请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46023098/