我昨天意識到,大多數Node.js的日誌庫似乎都使用阻塞/同步調用。日誌記錄通常是一個I/O操作,使用Node.js,我們應該在任何可能的地方使用非阻塞/異步I/O。基準測試Node.js日誌記錄系統 - 我是否遺漏了一些相關信息?
console.log
(process.stdout.write)一直以來的Node.js 0.6同步操作,TMK
我突然想到,對於做記錄語句的很多服務器,用於阻塞I/O這可能是一個很大的性能損失。
我跑了Redis的,FS,班揚和溫斯頓 「日誌」 的語句,我得到在MacBook Pro上的結果:
的Redis:16ms的
FS-寫流:90毫秒
本仁:414ms
溫斯頓:491ms
因此,使用Redis客戶端通過網絡I/O發送消息似乎是將數據從Node.js事件循環中取出的最快方式。
下面是測試:
// fs
var fs = require('fs');
// redis
var redis = require('redis');
var client = redis.createClient(); //connect to local redis db
// bunyan
var bunyan = require('bunyan');
var bunyanLogger = bunyan.createLogger({
name: 'benchmark',
streams: [
{
level: 'info',
path: '../bunyan_log.txt' // log ERROR and above to this file
}
]
});
// winston
var winston = require('winston');
var winstonLogger = new (winston.Logger)({
transports: [
new (winston.transports.File)({ filename: '../winston_log.txt' })
]
});
////////////////////////////////////////////////////////////////////////////
console.time('redis-time');
for (var i = 0; i < 12000; i++) {
client.set('key' + i, 'value' + i + 'aegeggaiojigfeijoagreoiraegioagrijogerawijogerwijogerijoegwoijegwijoegwjio');
}
console.timeEnd('redis-time');
////////////////////////////////////////////////////////////////////
console.time('fs-write-stream-time');
var wstream = fs.createWriteStream('../fs_log.txt');
for (var i = 0; i < 12000; i++) {
wstream.write('key' + i + 'value' + i + 'aegeggaiojigfeijoagreoiraegioagrijogerawijogerwijogerijoegwoijegwijoegwjio' + '\n');
}
wstream.end();
console.timeEnd('fs-write-stream-time');
///////////////////////////////////////////////////////////////
console.time('bunyan-time');
for (var i = 0; i < 12000; i++) {
bunyanLogger.info('bunyan' + i);
}
console.timeEnd('bunyan-time');
/////////////////////////////////////////////////////////////
console.time('winston-time');
for (var i = 0; i < 12000; i++) {
winstonLogger.info('bunyan' + i);
}
console.timeEnd('winston-time');
////////////////////////////////////////////////////////////////
我是對的東西還是我有什麼不對?
理想情況下,Node.js服務器看起來好像使用Redis將日誌記錄請求發送到某處的日誌服務器,這將處理隊列。
我也將它運行到系統日誌到/ dev/null並且得到了「syslog-time:54ms」,當我將bunyan記錄到/ dev/null並將winston記錄到/ dev/null時我得到了相同的結果 –