| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> Http2.0的一些思考以及Http3.0的优势 -> 正文阅读 |
|
[网络协议]Http2.0的一些思考以及Http3.0的优势 |
http的协议的发展也是经过了一个比较漫长的阶段,从最初的只支持get请求和纯文本的返回内容,到现在的各种文件,超文本...的传输,http协议毫无疑问是越来越强大了,而且,在这种演变中一定会有许多大佬的智慧的结晶,所有学习这些不仅可以丰富我们的知识,还能在某种程度上丰富自己的思维! 本文着重于1.0,2.0,3.0的版本的差异以及一些深层的原因。先从2.0开始. 一,二进制分帧 先解释一下,就是将一条连接上所有传输的信息,分割为更小的消息和帧(消息则是由一个或者多个帧组成的),并对他们采用二进制格式编码。首部信息放在Headers帧中,而主体信息被封装在Data帧中。而且在每个帧的首部都有一个标识位。那么问题就来了。 1.为什么2.0可以对所有的内容进行二进制转换? 因为二进制分帧层是在应用层和传输层之间的中间层,所有的信息都会从中经过,进而可以转换。 2.为什要用二进制? 首先就是效率会更高,计算机最喜欢处理二进制数了。除此之外就是可以根据帧头部的八个位来定义额外的帧。除了数据帧和头部帧,实际上还有PING帧、SETTING帧、优先级帧等等,为之后的多路复用打上坚实的基础。 3.有什么其他的好处? 还可以在一个连接上实现双向数据流以及乱序发送。因为在,每一个帧上都有一个标记位。浏览器和服务端双方可以前期乱序接收消息和帧。接收完毕按照标记位的排列来拼接成一整条信息。所以,浏览器并行发送的请求,服务器可以并行返回,而不需要按照顺序返回。 二,多路复用 简单来说,多路复用技术也是可以并行发送请求,而且无需等待响应返回的一种技术。消除了不必要的延迟,减少页面的加载时间。 1.和1.0的长连接的区别在哪? 1.0默认开启长连接,也就是保持tcp的连接不中断,可以一直发送http请求。但是长连接只能发送串行的请求,也就是一问一答式的,如果前一个请求的响应没有被接收,那么第二个请求不会发送,就会造成阻塞。而多路复用就是在一条tcp连接上,请求可以并行发送,而无需等待前面的响应返回。 2.和1.0的管道的区别? 管道也可以并行发送请求,但是返回响应的顺序则必须是发送时候的顺序。例如,发送A,B,C三个请求,那么返回的顺序就是A,B,C哪怕A返回之前,B,C已经准备好,依然要等到A返回,也容易造成阻塞。 实际上,多路复用的基础就是二进制分帧,因为可以乱序发送和接收,所以就不必担心接收错误消息的问题,接收完毕直接拼接。 三,首部压缩 首部压缩实现的一个核心预设就是,在第一次请求之后,大部分的字段可以复用的。而且随着页面越来越复杂,同一个页面发出的请求会越来越多。如果头部不压缩的话,会造成很大的流量开销。 1.那么首部压缩的原理是什么呢? 支持http2.0的浏览器和服务器会维护一个相同的静态表和一个动态表,以及内置一个霍夫曼编码表。静态表存储的是常见的一些头部,和一些很常见的头部键值对,例如method:get以及cookie。动态表开始是空的,如果头部命中静态表中的名称,那么就回将这份键值对加入动态表中,例如cookie:xxxx。这样做的原因在于,请求或则响应头命中了静态或者动态表的时候,只需要一个字节就能表示,可想而知,这个字节就是一个地址,指向表中的数据。来张大佬的图或许更加清晰。 ?而且像cookie对应的值可以由霍夫曼编码,来压缩体积。本质上,还是基于二进制分帧的数据转换。 2.如果静态和动态表中都没有相应的字段怎么办? 可以知道的是,键和值都是长度不确定的,所以两者都提倡采用霍夫曼编码,而且在帧流中,都是以01000000作为起始字节作为标识,这是一个“外来家伙”。添加到动态表中。 四.请求优先级 客户端可以在发出的Headers帧中包含优先次序信息来为流指定优先级。也可以专门在Priority帧来改变流的优先级。具体实现就,是每个流都可以带有一个31比特的优先值:0 表示最高优先级;2的31次方-1 表示最低优先级。而服务器则根据优先级作为交互数据的依据,在响应数据准备好之后,优先将最高优先级的帧发送给客户端。 1.高优先级的流一定得排在低优先级流的前面吗? 不一定。高优先级的流不是绝对先发出。因为强制的规定可能会造成阻塞:低优先级的流会等待高优先级的流。 2.常见的高优先级的流是哪些? ●优先级最高:主要的html ●优先级高:CSS文件 ●优先级中:js文件 ●优先级低:图片/视频 五.服务器推送 简单来说,服务器可以对一个客户端请求发送多个响应,例如,浏览器向服务端请求index.html,里面包含一张样式表和一张图片。传统的方法就是会向浏览器发送三次请求。而服务端推送,则可以在一次请求内将这三个文件全部发送给浏览器,减少了请求次数,提升了网页性能。下面是网上关于http2.0的性能提升的,比1.0里面的将资源内嵌到网页中都要高。 ? 1.不同域之间可以推送吗? 不可以。服务端推送也是遵守同源策略。 2.服务端推送有什么弊端? 如果服务端推送的内容,浏览器有缓存的话,就会浪费带宽。避免的方法就是在服务端配置,只对第一次请求实现服务器的推送。 好了,至此Http2.0的优势可以说是比Http1.0进步了许多。可以看到,2.0里面的大部分功能都是建立在二进制分帧这个基础的技术上,所以或许这也是他被称作2.0的理由吧。但是问题来了,Http2.0就是无懈可击了吗?还有没有他无法解决或者回避解决的问题?答案是肯定的。接下来来到Http3.0的神奇世界,看一看降维打击。 Http3.0相对于Http2.0是一种脱胎换骨的改变! 大家都知道,http协议是应用层协议,都是建立在传输层之上的。我们也都知道传输层上面不只有TCP协议,还有另外一个强大的协议UDP协议,2.0和1.0都是基于TCP的,因此都会有TCP带来的硬伤以及局限性。而Http3.0则是建立在UDP的基础上。所以其与Http2.0之间有质的不同。 Google率先推出的QUIC(quick UDP Internet Connection)就是很好的实践。 ?那么Http3.0具体有什么特性呢? 一,连接迁移 先阐述一下tcp里面的四元组,一条tcp的唯一性标识,是由源IP,源端口,目的IP,目的端口,四元组标识。源IP,源端口一般比较稳定,但是目的IP,目的端口会由于网络元素等原因发生改变,一旦改变,那么此条tcp连接就会断开。 由于QUIC基于UDP协议,所以一条UDP协议不再由四元组标识,而是以客户端随机产生的一个64位数字作为ID标识。只要ID不变,那么这条UDP就会存在,维持连接,上层业务逻辑就感受不到变化。 二,无队头阻塞 首先来看队头阻塞问题的的两层原因: ?我们知道,http2.0的多路复用正好解决了http层的队头阻塞,但是tcp的队头阻塞依然存在。因为当数据包超时确认或者丢失,会等待重传,因此会阻塞当前窗口向右滑动,造成阻塞。而QUIC是基于udp的,创新点在于QUIC依靠一个严格的单调递增的packet序列,一个数据包里面还会有streamID和streamoffset偏移量,即使中途发生丢包或者超时确认,后面的数据包不会等待,等到接收完之后根据ID和offset即可完成重新拼装,从而避免了这种问题。 三,自定义的拥塞控制 tcp协议是在传输层,默认存在于系统中,而QUIC在应用层,当想要依据实际情况来重定义拥塞算法的时候,QUIC显然更加灵活。Google提出了cubic和newreno提供了许多可供编程的接口。当然,和tcp一样,也是默认采用cubic算法。 那么tcp的拥塞怎么控制的呢? 这一块其实知识也挺多,简单来说就是,拥塞窗口前期会指数增加,直到到达一个阈值,然后就开始线性增加,直到出现超时事件,窗口大小到达最大值MAX。之后窗口调整为初始值,开始同样的增长,阈值减小为MAX/2。但是超时不一定是因为拥塞,也可能是因为丢包,那怎么办呢?如果从最初开始增加,那么显然会比较慢,等到发送方连续收到3个接收方发出的丢包ACK,直接让窗口大小等于阈值,再线性增长。这也有一个响亮的名字,快速恢复算法。 四,前向安全和前向纠错 都说udp不太靠谱,但是Google给QUIC加上了这个机制:每发送一组数据之后,就对这组数据进行异或运算(效率高),并将结果也发送出去,那么接收方就有两份数据版本,可以对初始数据进行纠错和校验。以此保证了可靠性。 写了这么多,但是也只能说我个人的一些浅层的思考,就像react一样,这些知识都是先辈们历经好多年打造出来的东西,要想做到深层次的掌握肯定是需要透彻研究的,我也会努力继续研究学习,学习知识的同时也学习思考方法。 当然了http0.9协议虽然简陋,但是我觉得那才是真正的创新,真正的从零到一。 本期就到这里啦,如果有小伙伴发现错误或者逻辑不严谨的地方,烦请指正!共同进步! |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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年12日历 | -2024/12/28 21:01:17- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |