我需要询问 1100 万个名称服务器,并找出其中哪些还活着。在 Java 中,我使用异步套接字发送 udp 请求,一切正常,直到我尝试使用多线程。速度成比例上升,但积极响应急剧下降,尽管我使用的是高性能 16 核集群。 我为每个线程创建了一个单独的 channel ,但没有发现发生这种情况的明显原因。谁能解释我做错了什么,可以在线程中使用不同的异步套接字吗?
这是一些代码。所以我有很多带有 id 的线程和它的主机列表,每个线程都执行以下操作:
@Override
public void run() {
DatagramChannel channel = null;
try {
channel = DatagramChannel.open();
InetSocketAddress isa = new InetSocketAddress(Settings.LOCAL_PORT+id);
channel.socket().bind(isa);
channel.configureBlocking(false);
Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
ByteBuffer outBuffer = ByteBuffer.wrap(Settings.QUERY);
ByteBuffer inBuffer = ByteBuffer.allocate(200);
while (true) {
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (!key.isValid()) {
continue;
}
if (key.isReadable()) {
inBuffer.clear();
channel.receive(inBuffer);
inBuffer.flip();
inCounter++;
//some analize of response
continue;
}
if (key.isWritable()) {
if (outCounter < hosts.size()) {
channel.send(outBuffer, new InetSocketAddress(hosts.get(outCounter), Settings.DNS_PORT));
outBuffer.flip();
outCounter++;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (channel != null)
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最佳答案
由于 UDP 是一种不可靠的协议(protocol),您必须小心不要让您的系统过载,否则您的网络缓冲区或数据包将会丢失。如何做到这一点可能对许多因素很敏感,所以如果稍微不同地做这件事可以提高您的响应率,我并不感到惊讶。
您使用的是 UDP 数据报还是 TCP 套接字?为什么要尝试轮询 1100 万个名称服务器?
关于Java Async Sockets 多线程性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7944808/