HTTP請求都要通過TCP三次握手創建鏈接,四次分手斷開連,若是每一個HTTP請求都要創建TCP鏈接的話是極其費時的,所以HTTP/1.1中瀏覽器默認開啓了Connection: keep-alive
。nginx
let request = require('request');
router.get('/http1', (req, res, next) => {
request({
method: 'GET',
uri: 'http://xxx:8887/xxx'
}, (error, response, body) => {
console.log('response', response);
});
});
複製代碼
在Node中咱們常常使用是request模塊來發送HTTP請求,那麼就作一個實驗,先向這個8887端口發送請求,結束後再看下這個鏈接是否還在。
...
json
Connection: keep-alive
。
request({
method: 'GET',
uri: 'http://xxx:8887/xxx',
headers: {
Connection: 'keep-alive'
}
}, (error, response, body) => {
console.log('response', response);
});
複製代碼
結果仍是和上面同樣,鏈接數仍是0,翻看request的文檔,原來並非這麼設置,而是使用forever這個配置promise
request({
method: 'GET',
uri: 'http://xxx:8887/xxx',
forever: true // 這個很重要 開啓keep-alive
}, (error, response, body) => {
console.log('response', response);
});
複製代碼
此次,在請求結束後,8887端口還存在一個鏈接,
keep-alive
已經生效了,這個鏈接會保持多久?通常在nginx中有設置,默認65s。
router.get('/http1', (req, res, next) => {
async function fn() {
for (let i = 0; i < 10; i ++) {
await new Promise((resolve, reject) => {
request({
method: 'GET',
uri: 'http://xxx:8887/xxx',
time: true, // 配置這個屬性能夠看到時間信息
forever: true
}, (error, response, body) => {
console.log('timingPhases', response.timingPhases);
resolve();
});
});
}
return 'success';
}
fn().then(()=>{
res.json({
msg: 'end'
});
});
});
複製代碼
能夠看到只有第一次的請求消耗了tcp的時間,以後的都是複用了以前創建的TCP鏈接,至於dns爲0是由於沒有使用域名。
keep-alive
及驗證。
router.get('/http1con', (req, res, next) => {
let promiseArr = [];
for (let i = 0; i < 10; i ++) {
let newP = new Promise((resolve, reject) => {
request({
method: 'GET',
uri: 'http://xxx:8887/xxx',
time: true,
forever: true
}, (error, response, body) => {
resolve();
});
});
promiseArr.push(newP);
}
Promise.all(promiseArr).then(() => {
res.json({
'msg': 'end'
});
});
});
複製代碼
能夠看到HTTP/1.1並行請求的時候會創建多個TCP鏈接,在瀏覽器中針對同一域名只能夠同時創建6個鏈接,雖然Node中沒有這個限制,但如何讓多個同時的請求也使用同一個TCP鏈接呢?固然是有辦法的,這就須要使用到HTTP/2.0中的單一長鏈接了,以後再來分析HTTP/2.0。