2

浅谈HTTP长连接

图片描述

HTTP长连接这个说法很久之前就听说过,而且打开F12进行调试的时候也频繁看到keep-alive的http请求。虽然经常遇到,不过对于长连接还是处于一种懵懂状态。正好今天上班比较闲,静下心来仔细研究了一番。

对长连接的理解

如今所使用的HTTP协议基本上都是1.1的,默认为长连接。也就是说一个HTTP请求的响应头里面,默认会有这么一行代码:Connection:keep-alive。HTTP长连接允许了HTTP设备在请求结束之后将TCP连接保持在打开的状态,以便为之后的HTTP请求重用现存的连接。从本质上来讲,HTTP仅仅是应用层的协议,TCP才是真正的传输层协议,因此TCP才有真正的长连接短连接的说法。

短连接的步骤为:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接

长连接的步骤为:建立连接——数据传输...(保存连接)...数据传输——关闭连接

长连接的带来的好处是显而易见的,它复用了TCP通道。通俗的来说,使用短连接发起多个HTTP请求时,每次都会去重新建立TCP连接,这样会造成严重的资源浪费。若采用长连接,什么三次握手四次挥手可能只需要进行一次,这无疑减少了很多消耗。

当然,长连接也并不是永久无限制的连接。服务器能够对长连接进行限制。

Connection:Keep-Alive
Keep-Alive:max=5,timeout=120

像上面这样的HTTP响应头,说明服务器最多还会为另外5个事务保存连接打开的状态或者保持连接打开状态至空闲120秒后。

测试

本着治学严谨的态度,我对此进行了测试,比较HTTP请求长连接与短连接之间的耗时。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <button id="button">点击发起请求</button>
</body>
<script>
  document.getElementById('button').onclick = () =>{
    let arr = [];
    let i = 1000
    while(i){
      arr.push(fetch('/json'));
      i--;
    }
    let start = new Date().getTime();
    Promise.all(arr).then(()=>{
      let stop = new Date().getTime();
      console.log(stop-start);
    })
  }
</script>
</html>

点击按钮,向后台发起1000次请求,计算出1000次请求的耗时。

后台使用了koa框架,代码如下

//...以上省略一万行代码
//短连接
router.get('/json', async (ctx, next) => {
  ctx.set('Connection','close');
  ctx.body = {
    title: 'hello world'
  }
})

//不设置response.header,默认长连接
router.get('/json', async (ctx, next) => {
   ctx.body = {
    title: 'hello world'
  }
})

通过测试,短连接响应1000次请求的时间平均为1900ms,长连接的平均响应时间为1500ms。由此可见,长连接对于效率的提升是非常显著的。(这个测试还意外的测试出了火狐浏览器对于多请求同时进行方面存在不足)。

若存在理解上的错误,欢迎指出,欢迎访问我的个人网站


york_lin
220 声望4 粉丝