Node.js 具有IP地址的流式数据的节点maxmind用法

Node.js 具有IP地址的流式数据的节点maxmind用法,node.js,node-modules,fs,maxmind,Node.js,Node Modules,Fs,Maxmind,我有IP地址的流式数据。在将数据放入数据库之前,我想将IP转换为经度和纬度 这就是我所做的,但它引起了一些问题。我还尝试将locationObject置于for循环之外。奇怪的是,它占用了大量内存。我知道这是阻塞代码,但它应该很快。虽然我看到了内存问题,因为数据对象不断地来自一个流,而每个数据对象都是巨大的 for (var i ==0; i < data.length; i++){ if (data.client_ip !== null) { va

我有IP地址的流式数据。在将数据放入数据库之前,我想将IP转换为经度和纬度

这就是我所做的,但它引起了一些问题。我还尝试将locationObject置于for循环之外。奇怪的是,它占用了大量内存。我知道这是阻塞代码,但它应该很快。虽然我看到了内存问题,因为数据对象不断地来自一个流,而每个数据对象都是巨大的

for (var i ==0; i < data.length; i++){
        if (data.client_ip !== null) {
            var locationLookup = maxmind.openSync('./GeoIP2-City.mmdb');
            var ip = data.client_ip;
            var maxmindObj = locationLookup.get(ip);
            locationObject.country = maxmindObj.country.names.en;
            locationObject.latitude = maxmindObj.location.latitude;
            locationObject.longitude = maxmindObj.location.longitude;
           }
}
但我不认为这是一个好的dea把它放在一个循环

我该怎么办?我每分钟都在获取数据对象


我不知道为什么您认为每次循环读取数据库文件都是快速阻塞代码并不等于快速代码,最好先读取一次数据库文件,然后循环数据

maxmind.openSync将把整个数据库读入内存,如下所述:

注意同步版本!因为mmdb文件相当大 城市数据库约为100Mb fs.readFileSync块 进程将文件读入缓冲区

如果没有多余的内存,唯一的其他选择是异步打开文件。同样,不是在循环内部,而是在循环外部:

maxmind.open("./GeoIP2-City.mmdb", (err, locationLookup) => {
  for (var i = 0; i < data.length; i++) {
    if (data.client_ip !== null) {
      var ip = data.client_ip;
      var maxmindObj = locationLookup.get(ip);
      locationObject.country = maxmindObj.country.names.en;
      locationObject.latitude = maxmindObj.location.latitude;
      locationObject.longitude = maxmindObj.location.longitude;
    }
  }
});

我唯一担心的是,随着时间的推移,我多次调用这个函数。每次我的消费者读到kakfa的jsonObject时,每分钟都在发生。还有更好的方法来优化它吗。所以我每分钟都调用这个函数。如何更好地进一步优化此功能

function processData(jsonObject) {
    maxmind.open('./GeoIP2-City.mmdb', function(err, locationLookup) {
        if (err) {
            logger.error('something went wrong on maxmind fetch', err);
        }
        for (var i = 0; i < jsonObject.length; i++) { ...}
})
}

我理解你的建议。对我来说,这个函数的问题是,我有多次调用这个函数。我每分钟都以非常高的数据流获取数据对象。每次接收到数据对象时,我都解析循环中的所有字段,包括IP。这意味着每次文件都会被打开。有没有其他方法可以在不使用该文件的情况下查询maxmind?maxmind.openSync将把整个数据库读入内存。我的实例上有100mb的内存,但问题是当我使用pm2运行它时,内存一直在增加。不确定GC是否运行cleanup无论您选择哪种解决方案,都应该只打开/读取数据库一次。如果函数多次被调用,并且您希望异步打开数据库文件,那么应该在函数外部打开它。这取决于您的应用程序结构,最好的解决方案是什么。谢谢。让我做一些试验和测试。监控内存等,并将结果反馈给您进行了一些测试。我发现您的解决方案绝对是处理我的用例的最佳方式。垃圾收集器工作正常,如果我在异步循环之外打开它,内存将保持控制。你能看看我发布的答案,告诉我如何更好地处理它吗。谢谢你在这方面的帮助。您的解决方案工作正常,但我只是想确保我已经准备好进行长期运行。我不建议每次调用函数时都打开该文件:在应用程序启动时打开它一次,然后传递locationLookup。听起来不错。进行了更改,现在运行良好。感谢您的帮助和反馈。这很有帮助。
function processData(jsonObject) {
    maxmind.open('./GeoIP2-City.mmdb', function(err, locationLookup) {
        if (err) {
            logger.error('something went wrong on maxmind fetch', err);
        }
        for (var i = 0; i < jsonObject.length; i++) { ...}
})
}