IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 关于HTTP中的Connection长连接 -> 正文阅读

[网络协议]关于HTTP中的Connection长连接

关于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有服务端自动推送的功能,此处不再赘述

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 01:33:50  更:2022-02-19 01:34:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:43:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码