HTTP请求都要经过TCP三次握手建立连接,四次分手断开连,如果每个HTTP请求都要建立TCP连接的话是极其费时的,因此HTTP/1.1中浏览器默认开启了Connection: keep-alive
。
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端口发送请求,结束后再看下这个连接是否还在。
...
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这个配置
request({
method: 'GET',
uri: 'http://xxx:8887/xxx',
forever: true // 这个很重要 开启keep-alive
}, (error, response, body) => {
console.log('response', response);
});
keep-alive
已经生效了,这个连接会保持多久?一般在nginx中有设置,默认65s。接下来看下,使用长连接后,是否省去了TCP的时间。
串行上面的请求10次来实验。
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'
});
});
});
以上就是在Node中如何使用
keep-alive
及验证。顺便看下,如果是并行请求,会建立多少个TCP连接呢?
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'
});
});
});