通信技术|从起源到发展 详说HTTP从1到3的演变( 六 )
如果第一、二、三个的包都丢失了也没有关系,当发送方收到第四个包时,它可以确信一定是前三个 ACK 丢了而不是数据包丢了,否则不会收到 4001 的 ACK,所以发送方可以大胆的把窗口向后滑动四位 。
滑动窗口的概念大幅度提高了 TCP 传输数据时抗干扰的能力,一般丢失一两个 ACK 根本没关系 。但如果是发送的包丢失,或者出错,窗口就无法向前滑动,出现了队头阻塞的现象 。
QUIC 是如何做的
文章图片
QUIC 协议基于 UDP 实现,我们知道 UDP 协议只负责发送数据,并不保证数据可达性 。这一方面为 QUIC 的多路复用提供了基础,另一方面也要求 QUIC 协议自己保证数据可达性 。
SPDY 为各个数据包做好标记,指明他们属于哪个 HTTP 请求,至于这些包能不能到达客户端,SPDY 并不关心,因为数据可达性由 TCP 协议保证 。既然客户端一定能收到包,那就只要排序、拼接就行了 。QUIC 协议采用了多路复用的思想,但同时还得自己保证数据的可达性 。
TCP 协议的丢包重传并不是一个好想法,因为一旦有了前后顺序,队头阻塞问题将不可避免 。而无序的数据发送给接受者以后,如何保证不丢包,不错包呢?这看起来是个不可能完成的任务,不过如果把要求降低成:最多丢一个包,或者错一个包 。事情就简单多了,操作系统中有一种存储方式叫 RAID 5,采用的是异或运算加上数据冗余的方式来保证前向纠错(FEC: Forward Error Correcting) 。QUIC 协议也是采用这样的思想,这里不再赘述 。
利用冗余数据的思想,QUIC 协议基本上避免了重发数据的情况 。当然 QUIC 协议还是支持重传的,比如某些非常重要的数据或者丢失两个包的情况 。
少 RTT,请求更快速
前面说到,一次 HTTPS 请求,它的基本流程是三次 TCP 握手外加四次 SSL/TLS 握手 。也就是需要三个 RTT 。但是 QUIC 在某些场景下,甚至能够做到 0RTT 。
首先介绍下什么是 0RTT 。所谓的 0RTT 就是通信双方发起通信连接时,第一个数据包便可以携带有效的业务数据 。而我们知道,这个使用传统的TCP是完全不可能的,除非你使能了 TCP 快速打开特性,而这个很难,因为几乎没人愿意为了这个收益去对操作系统的网络协议栈大动手脚 。未使能 TCP 快速打开特性的TCP传输第一笔数据前,至少要等1个RTT 。
我们这里再说说 HTTP2 。对于 HTTP2 来说,本来需要一个额外的 RTT 来进行协商,判断客户端与服务器是不是都支持 HTTP2,不过好在它可以和 SSL 握手的请求合并 。这也导致了一个现象,就是大多数主流浏览器仅支持 HTTPS2 而不单独支持 HTTP2 。因为 HTTP2 需要一个额外的 RTT,HTTPS2 需要两个额外的 RTT,仅仅是增加一个 RTT 就能获得数据安全性,还是很划算的 。
TCP 快速打开
何谓 TCP 快速打开,即客户端可以在发送第一个 SYN 握手包时携带数据,但是 TCP 协议的实现者不允许将把这个数据包上传给应用层 。这主要是为了防止 TCP 泛洪攻击 [http://techimg88.guangdonglong.com/img.php?https://tools.ietf.org/html/rfc4987] 。
因为如果 SYN 握手的包能被传输到应用层,那么现有的防护措施都无法防御泛洪攻击,而且服务端也会因为这些攻击而耗尽内存和 CPU 。
当然 TCP 快速打开并不是完全不可行的 。人们设计了 TFO (TCP Fast Open),这是对 TCP 的拓展,不仅可以在发送 SYN 时携带数据,还可以保证安全性 。
TFO 设计了一个 Cookie,它在第一次握手时由 server 生成,Cookie 主要是用来标识客户端的身份,以及保存上次会话的配置信息 。因此在后续重新建立 TCP 连接时,客户端会携带 SYN + Cookie + 请求数据,然后不等 ACK 返回就直接开始发送数据 。
文章图片
服务端收到 SYN 后会验证 Cookie 是否有效,如果无效则会退回到三次握手的步骤,如下图所示:
文章图片
同时,为了安全起见,服务端为每个端口记录了一个值 PendingFastOpenRequests,用来表示有多少请求利用了 TFO,如果超过预设上限就不再接受 。
关于 TFO 的优化,可以总结出三点内容:
- TFO 设计的 Cookie 思想和 SSL 恢复握手时的 Session Ticket 很像,都是由服务端生成一段 Cookie 交给客户端保存,从而避免后续的握手,有利于快速恢复 。
- 第一次请求绝对不会触发 TFO,因为服务器会在接收到 SYN 请求后把 Cookie 和 ACK 一起返回 。后续客户端如果要重新连接,才有可能使用这个 Cookie 进行 TFO
- TFO 并不考虑在 TCP 层过滤重复请求,以前也有类似的提案想要做过滤,但因为无法保证安全性而被拒绝 。所以 TFO 仅仅是避免了泛洪攻击(类似于 backlog),但客户端接收到的,和 SYN 包一起发来的数据,依然有可能重复 。不过也只有可能是 SYN 数据重复,所以 TFO 并不处理这种情况,要求服务端程序自行解决 。这也就是说,不仅仅要操作系统的支持,更要求应用程序(比如 MySQL)也支持 TFO 。
推荐阅读
- |潍坊新昌发展区:城市管理有妙招 用好诚信积分制
- 教育信息化|西藏:推动教育信息化发展建设“数字校园”
- 怀进鹏|怀进鹏:汇聚中小企业力量推动数字经济合作发展
- TikTok|海外发展受阻国内拓展新领域字节跳动的全球平衡术
- OLEDOLED面板出货量|2020年全球OLED市场发展现状和供需分析预测 全球OLED面板预期出货4.65亿片
- 可再生能源可再生能源发电|2020年全球可再生能源发展趋势投资前景 全球可再生能源发电规模放缓至6%
- 通信技术|印度首富宣布成功研发5G技术:献给莫迪“自力更生的印度”计划
- 农业|我国首次对乡村产业发展做出全面规划乡村产业,等你来
- 通信技术|国家统计局:上半年全国光缆产量1.32亿芯千米
- 聚乙烯塑料购物袋|2020年聚乙烯市场发展现状和前景 中国明年禁用不可降解塑料购物袋