某天,河蟹君遇到一個(gè)需求,統(tǒng)計(jì)express服務(wù)器得api相應(yīng)時(shí)間?;舅悸肥牵寒?dāng)請求過來得時(shí)候,記錄一下當(dāng)前時(shí)間t1,然后api響應(yīng)結(jié)束時(shí)間是t2, 響應(yīng)時(shí)間 = t2 - t1
嗯,實(shí)現(xiàn)思路很清晰,另外,最好利用express的中間件機(jī)制來實(shí)現(xiàn),這樣才能夠做到,足夠的通用性,監(jiān)聽所有api的響應(yīng)情況。
那么問題來了,需要知道中間件是從將請求處理,從一個(gè)中間件的數(shù)據(jù)流到另外一個(gè)中間件知道數(shù)據(jù)輸出,我們雖然能夠輕松地記錄到t1,但是t2 卻因?yàn)檫@種模型而變得獲取困難,難道我們需要再每次響應(yīng)的時(shí)候,特意記錄一下t2,想想都覺得是一個(gè)非常龐大的工程。
如果你也遇到這種問題,河蟹君,確實(shí)有個(gè)辦法解決
exports.responseTime = function () {
return function (req, res, next) {
req._startTime = new Date() // 獲取時(shí)間 t1
var calResponseTime = function () {
var now = new Date(); //獲取時(shí)間 t2
var deltaTime = now - req._startTime;
console.log(deltaTime);
}
res.once('finish', calResponseTime);
res.once('close', calResponseTime);
return next();
}
}
使用中間件
app.use(responseTime())
express 里面擁有一個(gè)事件機(jī)制,通過監(jiān)聽 finish 和 close 事件,可以知道請求到底什么時(shí)候結(jié)束,監(jiān)聽這個(gè)事件,并在事件處理的過程當(dāng)中,獲取t2 ,計(jì)算出響應(yīng)時(shí)間,這里值得注意的是,監(jiān)聽的方法是once,即監(jiān)聽一次后,并自動解除監(jiān)聽,如果用了on 方法,每次請求都會產(chǎn)生一次監(jiān)聽,請求多了,內(nèi)存會泄漏,這里需要十分注意。