2017-10-06 124 views
0

我使用IP地址傳入數據流。我想在將數據放入我的數據庫之前將IP翻譯爲經度和緯度。使用IP地址流式傳輸數據的node-maxmind用法

這就是我正在做的,但它造成了一些問題。我也嘗試把forObject放在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; 
      } 
} 

再次試圖把maxmind.openSync( './ GeoIP2-City.mmdb');外部循環引起內存的巨大增加。

另一種選擇是使用非阻塞代碼

maxmind.open('/path/to/GeoLite2-City.mmdb', (err, cityLookup) => { 
    var city = cityLookup.get('66.6.44.4'); 
}); 

但我不認爲這是一個很好的DEA把這個循環中。

我該如何處理?我得到的數據對象的每一分鐘

https://github.com/runk/node-maxmind

回答

1

我不知道爲什麼你認爲閱讀對於循環的每個迭代的數據庫文件將是快速(「堵代碼」不等於「快速代碼」 ),一次讀取數據庫文件然後在data上循環會更好。

maxmind.openSync()將讀取整個數據庫到內存中,這是在README提到:

小心同步版本!由於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; 
    } 
    } 
}); 
+0

我明白你在暗示什麼。對我來說這個問題是我有多次調用這個函數。我以非常高的速度獲取數據對象(每分鐘數據流)。每次接收到數據對象時,我都會解析循環中的所有字段,包括IP。這意味着每次都會打開該文件。有沒有其他的方式來查詢maxmind而不使用該文件? maxmind.openSync()會將整個數據庫讀入內存。我的實例有100mb,但問題是當我使用pm2運行它時,內存不斷增加。不確定GC是否運行清理 –

+0

無論您選擇哪種解決方案,您都應該打開/讀取數據庫一次。如果該函數被調用了很多,並且想要異步打開該數據庫文件,則應該在函數之外打開它。這取決於您的應用程序結構是什麼最佳解決方案。 – robertklep

+0

好的。非常感謝。讓我做一些試驗和測試。監視內存等,並回到你的結果 –

0

我唯一擔心的是隨着時間的推移,我將這個函數調用了很多次。每次我的消費者從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++) { ...} 
}) 
} 
+1

我不建議在每次調用函數時打開該文件:打開一次,當您的應用程序啓動時,並傳遞'locationLookup'。 – robertklep

+0

聽起來不錯。現在做出改變並運行良好。感謝您的幫助和反饋。這非常有幫助。 –