关于HTTP中的Connection长连接

本文介绍了HTTP协议中的长连接和短连接概念,以及它们在网络请求中的应用。通过示例解释了如何通过设置'Connection: Keep-Alive'来维持长连接,以实现TCP链接的复用,提高效率。同时讨论了HTTP1.1的并发限制和HTTP2的信道复用技术,说明了长连接在降低开销和提升速度上的优势。

关于HTTP的Connection

  • HTTP的请求是在TCP的链接上发送的
  • TCP的链接又分为长连接,短链接
  • HTTP的请求要先去创建一个TCP的链接
  • 然后在TCP的链接上将HTTP的请求发送并且接受完返回
  • 这时候一次HTTP请求已经结束了,浏览器和服务端就会考虑是否关闭这个TCP链接
  • 如果不关闭,这个TCP链接就会一直开着,就会有一定的消耗
  • 如果接下去还有请求,可以直接在这个TCP链接上发送,就不需要进行三次握手来创建链接的消耗
  • 如果直接关闭,代表了下次请求的时候,又要去重新创建链接,这就会有一个网络延迟的开销,但会减少客户端和服务端链接的并发数
  • 但是实际使用中,每次创建链接并关闭这种策略的话,会影响效率,实际的网站并发量比较大,这样实际的开销会远远超过保持长连接的策略
  • 实际上,长链接可以设置链接的超时功能Timeout(过了一段时间没有请求会自动关闭), 所以保持长连接才是最好的策略
  • 举个实际的例子
    • 打开百度网站,浏览器打开控制台,切换到Network选项中,勾选上Disable cache
    • 刷新页面,在All次级选项页面上所有资源列表中右键勾选上Connection ID这一项,在列表中就会多出现一项Connection ID
    • 这个Connection ID就代表了TCP链接的ID,这样我们就可以区分是否是同一个链接
    • 我们可以看到这个这个Connection ID列中有很多资源使用了相同的ID, 在不同的域下使用不同的ID, 同域下尽量复用这些链接ID
    • 在HTTP1.1的TCP链接其发送请求的策略是有先后顺序的,比如有10个请求是不可以并发的在一个TCP链接上去发送
    • 在一个TCP链接上只能一个接着一个的发送,而我们希望网站在加载首页的时候,能够并发进行,这样会提高效率
    • 这时候,浏览器允许并发的创建TCP链接,Chrome允许的是6个并发TCP的链接数量
    • 所以,在加载首页的时候,会使用6个并发TCP链接, 全部使用完成之后才能继续进行并发
    • 比如有10个要进行并发,会先进行6个并发的创建,在这6个中,至少有一个完成,才能继续依次进行
  • 如何保证浏览器创建的是长连接而非短链接呢
    • 点击任意一个连接,在响应头上的头信息中,一般会有Connection: Keep-Alive
    • 这就代表链接是被保持的,就代表请求不会一下子被关闭
    • 在请求头的头信息中,也一般有一个Connection: Keep-Alive
    • 这里有一个协商的过程,在发送请求的时候,浏览器是希望服务端是保持长链接的
    • 如果服务端选择不保持,浏览器端还是会选择关闭掉

程序示例

  • test.html

    <img src='/test1.jpg'>
    <img src='/test2.jpg'>
    <img src='/test3.jpg'>
    <img src='/test4.jpg'>
    <img src='/test5.jpg'>
    <img src='/test6.jpg'>
    <img src='/test7.jpg'>
    
  • server.js

    const http = require('http');
    const fs = require('fs');
    
    http.createServer((req, res) => {
        console.log('req come: ', req.url);
        if(req.url === '/') {
            const html = fs.readFileSync('test.html', 'utf8');
            // 默认是下面这个writeHead设置,不写也可以
            res.writeHead(200, {
                'Content-Type': 'text/html'
            });
            res.end(html);
        } else {
            // 此处显示图片
            const img = fs.readFileSync('test.jpg');
            res.writeHead(200, {
                'Content-Type': 'image/jpg'
            });
            res.end(img);
        }
    }).listen(8000, () => {
        console.log('server is running on port 8000');
    });
    
  • 随便准备一张图片:test.jpg,启动程序 $ node server.js

  • 访问:http://localhost:8000/

  • 将浏览器模拟网络调整为较慢速的网络,设置Online -> Fast 3G

  • 打开浏览器Network中的Connection ID

  • 刷新页面,可以看到除了html页面的加载和第一张图片复用了一个ID

  • 其他的5张图片都是不同的Connection ID,说明浏览器进行了6个并发请求

  • 然后从Waterfall列(网络分时请求)中可见第7张图片是要等待的

  • 等待请求传输完成后发现它复用了第一张图片的Connection ID

  • 这就是TCP的并发

  • 我们可以把长连接修改成短链接,修改程序示例:

        const http = require('http');
        const fs = require('fs');
    
        http.createServer((req, res) => {
            console.log('req come: ', req.url);
            if(req.url === '/') {
                const html = fs.readFileSync('test.html', 'utf8');
                res.writeHead(200, {
                    'Content-Type': 'text/html',
                    'Connection': 'close' // 添加这行
                });
                res.end(html);
            } else {
                // 此处显示图片
                const img = fs.readFileSync('test.jpg');
                res.writeHead(200, {
                    'Content-Type': 'image/jpg',
                    'Connection': 'close' // 添加这行
                });
                res.end(img);
            }
        }).listen(8000, () => {
            console.log('server is running on port 8000');
        });
    
  • 重启程序并刷新浏览器后可发现,每一个Connection ID都是不同的,而且ID序号递增

  • 这就是没有重复利用TCP的链接,每次请求后链接就会被关闭

  • 我们在开发服务器时,可以合理利用这个Connection: Keep-Alive

  • 可以给当前TCP链接设置一个自动关闭的时间,这是服务端的设置和HTTP协议没有太大关系

  • 在HTTP2版本中, 有了一个信道复用的概念, 在TCP链接上可以并发的发送HTTP请求

  • 这表示着我们在访问网站时,可以使用一个TCP链接就可以了,这样就可以极大的降低开销

  • 可以打开谷歌网站查看HTTP2版本的使用,在同域下基本都是使用同一个Connection ID

  • 此时,开销会被降至最低,而且速度有一个本质的提升

  • 同时HTTP2有服务端自动推送的功能,此处不再赘述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值