We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTTP/2有着二进制报文、头部压缩、多路复用等特点,基本解决了HTTP/1.1中的队头堵塞问题,大幅提升了传输效率。
但它仍然存在以下问题:
要想计算HTTP/2建立连接的花费,先理解一个叫做RTT的术语。
RTT(Round-Trip Time)往返时间表示从发送端发送数据开始到接收到确认数据总共经历的时间,也就是通信一个来回的时间。
由于HTTP/2事实上都是加密的,也就是采用HTTPS的协议名,所以一个HTTP/2建立连接要经历以下过程:
总结来说一个HTTP/2首次建立连接最少要花费2个RTT,如果是TLS/1.2则要花费3个RTT。
如果服务器距离客户端很近,一个RTT时间 < 10ms,那么建立连接时间不会超过30ms,用户不会感知。但如果距离较远,相隔上万公里,一个RTT时间通常在200ms以上,那么建立连接就要花费600ms甚至1s以上,这就会影响到用户体验了。
因为 HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1.1 了。
因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
不难发现以上两个问题都是由TCP协议导致的,那么就有人想去修改TCP协议了。但这几乎是不可能的了,因为它已经存在了太久,充斥在各种设备中,并且这个协议是由操作系统实现的,更改起来不太现实。
但基于UDP又会带来新的问题,那就是UDP本身并不可靠,不能直接用。
于是谷歌决定在UDP基础上改造一个具备TCP协议优点的新协议,这么做有以下几点好处:
这个新协议就是QUIC协议(Quick UDP Internet Connection),并且使用在了HTTP/3上,所以HTTP/3之前叫做HTTP-over-QUIC。
QUIC协议是一个基于UDP,具有TCP优点的协议,它在UDP的基础上实现了很多新功能,这里我们主要了解几个主要的。
虽然HTTP/2支持多路复用,但TCP协议是没有这个功能的,QUIC原生实现了多路复用。
QUIC协议基于UDP协议,同一个QUIC连接上可以创建多个stream(数据流)来发送多个HTTP请求,并且,多个stream之间没有依赖,传输的单个stream可以保证有序交付且不影响到其他的stream。
所以,假如单个stream中的某个包丢了,不会影响到其他的stream被处理,也就解决了之前TCP存在的队头阻塞问题。
并且QUIC在移动端的表现也比TCP好,因为TCP是基于IP和端口来识别连接的,这种方式在多变的移动网络下很脆弱。QUIC则通过ID的方式去识别一个连接,不管网络环境如何变化,只要ID不变,就可以迅速重连上。
通过这张图可以看到左边的HTTPS需要2-3个RTT才能开始传输数据,而右边的QUIC协议在第一个包时就能够携带有效的应用数据。
当然QUIC实现0RTT也是有条件的,准确来说,首次连接是1RTT,后续建连才是0RTT。
首次连接过程:
可以看到,首次连接时,在第三步就开始发送实际的应用数据了,1-3步正好花费1RTT,所以QUIC首次连接的成本是1RTT。
后续连接时,会使用类似TCP快速打开的技术,实现0RTT。
QUIC有个独特的特性,称为向前纠错 (Forward Error Correction,FEC)。
每个数据包除了本身的内容外,还包括部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。
向前纠错极致牺牲了每个数据包可以发送数据的上限,但减少了因为丢包导致的数据重传的时间(包括确认数据包丢失、请求数据包重传、等待新数据包)。
假如说要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。
当出现其中的非校验包丢包的情况时,可以通过另外两个包和校验包计算出丢失的数据包的内容。
当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。
TCP头部没有经过任何加密和认证,所以在传输的过程中很容易被中间网络设备篡改,注入和窃听。比如修改包序列号、滑动窗口等。
QUIC的数据包可以说是武装到了牙齿。除了个别数据包外,所有数据包首部都是经过认证的,传输数据体都是经过加密的。
这样只要对QUIC数据包任何修改,接收端都能够及时发现,有效地降低了安全风险。
QUIC 协议虽然是基于 UDP 来实现的,但它将 TCP 的重要功能都进行了实现和优化,同时在加密传输方向的尝试也推动了TLS1.3的发展。
只是现在 TCP 协议的势力过于强大,很多网络设备甚至对于UDP数据包做了很多不友好的策略,所以现在暂时还是 TCP 的天下。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
HTTP/2和TCP的缺陷
HTTP/2有着二进制报文、头部压缩、多路复用等特点,基本解决了HTTP/1.1中的队头堵塞问题,大幅提升了传输效率。
但它仍然存在以下问题:
HTTP/2建立连接时间?
要想计算HTTP/2建立连接的花费,先理解一个叫做RTT的术语。
由于HTTP/2事实上都是加密的,也就是采用HTTPS的协议名,所以一个HTTP/2建立连接要经历以下过程:
总结来说一个HTTP/2首次建立连接最少要花费2个RTT,如果是TLS/1.2则要花费3个RTT。
如果服务器距离客户端很近,一个RTT时间 < 10ms,那么建立连接时间不会超过30ms,用户不会感知。但如果距离较远,相隔上万公里,一个RTT时间通常在200ms以上,那么建立连接就要花费600ms甚至1s以上,这就会影响到用户体验了。
TCP队头阻塞
因为 HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1.1 了。
因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
QUIC协议为什么基于UDP?
不难发现以上两个问题都是由TCP协议导致的,那么就有人想去修改TCP协议了。但这几乎是不可能的了,因为它已经存在了太久,充斥在各种设备中,并且这个协议是由操作系统实现的,更改起来不太现实。
但基于UDP又会带来新的问题,那就是UDP本身并不可靠,不能直接用。
于是谷歌决定在UDP基础上改造一个具备TCP协议优点的新协议,这么做有以下几点好处:
这个新协议就是QUIC协议(Quick UDP Internet Connection),并且使用在了HTTP/3上,所以HTTP/3之前叫做HTTP-over-QUIC。
QUIC新特性
QUIC协议是一个基于UDP,具有TCP优点的协议,它在UDP的基础上实现了很多新功能,这里我们主要了解几个主要的。
多路复用,解决队头阻塞
虽然HTTP/2支持多路复用,但TCP协议是没有这个功能的,QUIC原生实现了多路复用。
QUIC协议基于UDP协议,同一个QUIC连接上可以创建多个stream(数据流)来发送多个HTTP请求,并且,多个stream之间没有依赖,传输的单个stream可以保证有序交付且不影响到其他的stream。
所以,假如单个stream中的某个包丢了,不会影响到其他的stream被处理,也就解决了之前TCP存在的队头阻塞问题。
并且QUIC在移动端的表现也比TCP好,因为TCP是基于IP和端口来识别连接的,这种方式在多变的移动网络下很脆弱。QUIC则通过ID的方式去识别一个连接,不管网络环境如何变化,只要ID不变,就可以迅速重连上。
0RTT
通过这张图可以看到左边的HTTPS需要2-3个RTT才能开始传输数据,而右边的QUIC协议在第一个包时就能够携带有效的应用数据。
当然QUIC实现0RTT也是有条件的,准确来说,首次连接是1RTT,后续建连才是0RTT。
首次连接过程:
可以看到,首次连接时,在第三步就开始发送实际的应用数据了,1-3步正好花费1RTT,所以QUIC首次连接的成本是1RTT。
后续连接时,会使用类似TCP快速打开的技术,实现0RTT。
向前纠错
QUIC有个独特的特性,称为向前纠错 (Forward Error Correction,FEC)。
每个数据包除了本身的内容外,还包括部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。
向前纠错极致牺牲了每个数据包可以发送数据的上限,但减少了因为丢包导致的数据重传的时间(包括确认数据包丢失、请求数据包重传、等待新数据包)。
假如说要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。
当出现其中的非校验包丢包的情况时,可以通过另外两个包和校验包计算出丢失的数据包的内容。
当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。
加密认证的报文
TCP头部没有经过任何加密和认证,所以在传输的过程中很容易被中间网络设备篡改,注入和窃听。比如修改包序列号、滑动窗口等。
QUIC的数据包可以说是武装到了牙齿。除了个别数据包外,所有数据包首部都是经过认证的,传输数据体都是经过加密的。
这样只要对QUIC数据包任何修改,接收端都能够及时发现,有效地降低了安全风险。
总结
QUIC 协议虽然是基于 UDP 来实现的,但它将 TCP 的重要功能都进行了实现和优化,同时在加密传输方向的尝试也推动了TLS1.3的发展。
只是现在 TCP 协议的势力过于强大,很多网络设备甚至对于UDP数据包做了很多不友好的策略,所以现在暂时还是 TCP 的天下。
The text was updated successfully, but these errors were encountered: