【发布时间】:2015-12-04 11:22:26
【问题描述】:
我正在运行一个 for 循环来生成所有可能的 IPv4 地址,然后在 maxmind 的 mmdb 文件中查找它们。问题是,虽然 for 循环太快,但 maxmind 查找相对非常慢,因此进程变慢,最终我的系统在大约 400k 次迭代后冻结。如果我正在从某个流中读取数据,我会在读取每 10k 个 IP 地址后暂停该流,并且只有在从 mmdb 文件中查找完所有这些地址后才会恢复。但是我怎样才能对 for 循环进行这样的控制呢?
connectToMaxMindDatabases().then(function (done){
for(var i=0; i<256; i++){
for(var j=0; j<256; j++){
for(var k=0; k<256; k++){
for(var l=0; l<256; l++){
count++;
if(count % 1000 == 0){
console.log("count", count);
}
var newIP = getIPV4([i,j,k,l])
ispDB.getGeoDataAsync(newIP).then(function (result){
if(result){
console.log(count, newIP, result);
// process.exit();
}
});
}
}
}
}
})
function getIPV4(bytes){
return bytes.join(".")
}
【问题讨论】:
-
请注意,Node.js 有一个非阻塞的理念,所以我认为停止循环可能不是一个好的选择。也许某种排队?
-
您是否知道代码示例中的缺陷是因为
getGeoDataAsync是异步的,所以当它的结果返回时count将增加一个不可预测的数量?不确定它是否与您的逻辑相关,但肯定是您忽略了。 -
@marekful 我明白你的意思。但是,这不会导致任何问题,因为我需要处理所有的 IP 地址。如果不是 for 循环,而是一个文件,这不会引起任何问题,因为我会在读取每 1k 条记录后暂停流,并且仅在 maxmind 处理该数量的记录时才恢复。我会为此保留一个单独的柜台。但我同意亚当的观点,暂停 for 循环将是灾难性的。我正在考虑先将所有排列写入文件。
-
是的,我明白这个问题。它的根源肯定在底层 OS/Node 服务器的资源管理中。具有这种迭代次数的 for 循环将在该特定硬件上冻结,而在更强大的计算机上它可能只会稍后冻结或根本不冻结。解决方案是先将所有 IP 地址收集到一个数组中,然后以一次只处理一个段的方式处理它们,等到完成后再移动到下一个段。
-
你应该使用
mmdb-reader,它有一个相当快的同步接口。