【计算机网络】HTTP各版本区别

136 阅读8分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

HTTP1.0与HTTP1.1的区别

长连接

  • HTTP1.0默认适用短链接,客户端和服务器每进行一次HTTP交互就需要建立一次连接,任务结束就中断连接

    • TCP连接的重复建立和断开造成额外开销,增加服务端的负载
  • HTTP1.1默认使用长连接,只要任意一端没有明确提出断开连接,就一直保持TCP连接状态

Host域

  • HTTP1.0认为每一个IP地址对应唯一一台主机,因此请求消息中的URL不传递主机名,没有host域
  • HTTP1.1请求消息和响应消息都支持Host域且请求消息中如果没有Host域会报告错误400Bad Request

随着虚拟主机技术的发展,一台物理服务器上可以存在多个虚拟主机,共享一个IP地址,也就是说一个IP地址是可以对应多个域名的

比如一台IP为A的服务器上部署着谷歌、百度、淘宝的网站,在发送请求时域名解析会解析到同一个IP地址,那么如何区分用户是要具体访问主机中的哪一个应用

  • 使用ip+port区分

    • 需要为每个网站部署一个端口,客户端在访问的时候需要直到是哪一个端口
  • 虚拟主机

    • 将一台完整的服务器分成若个主机,可以在单一主机上运行多个服务,客户端就可以使用同一个ip和同一个端口号访问不同的网站,通过host域进行区分
    • 通过用户请求的host域名进行区分,服务器后台解析出host域并和服务器上设置的server_name比对,如果匹配则访问,不匹配则连接丢弃报错

管道网络传输

  • HTTP1.0需要收到第一个请求的回应后才可以发送第二个请求
  • HTTP1.1使用长连接,使管道网络传输成为可能。在同一个TCP连接中,客户端可以发起多个请求,只要第一个请求发送出去了就可以发送第二个,不需要等待第一个请求的返回,可以减少整体的响应时间

断点续传

  • HTTP1.0每次只会传输整个数据实体,没办法部分传输
  • HTTP1.1默认支持断点续传,原理是在请求报文头中加入Range字段段

消息通知管理

  • HTTP1.1新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源当前状态冲突;410(Gone)表示服务器上某个资源被永久性删除

缓存处理

  • HTTP1.0使用header中的if-modified-since和expires作为缓存判断标准
  • HTTP1.1引入了更多缓存控制策略如Entity tag,If-Unmodified-Since,If-match,If-None-Match等

节约带宽

  • HTTP1.0每次只会传输整个数据实体,没办法部分传输
  • HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器则返回100,客户端接收到100才把body发送给服务器;如果服务器返回401,则客户端就不需要发送body了,这个机制使得无权限情况下节约了传输body的带宽

HTTP1.1和HTTP2.0的区别

头部压缩

  • HTTP1.1中Header问题

    • 固定的字段占字节大
    • 大量的请求和响应报文中许多字段重复
    • 只对body进行压缩,没有对header进行压缩
  • HTTP2.0使用HPACK算法对header的数据进行压缩

    • HPACK算法:在客户端和服务器两端建立字典,将字段存入字典中并生成索引号,使用索引号代表字段了

      • 静态字典

        • 为高频出现在头部的字符串和字段建立静态表,写入HTTP/2框架中
      • 动态字典

        • 不在静态表范围内的头部字符串要自行构建动态表,Index从62起步,在编码解码的时候随时更新,下一次发送的时候就只需要发送一个字节的index
        • 必须同一个连接上重复传输完全相同的HTTP头部
        • 占用内存越来越大
    • 哈夫曼编码压缩整数和字符串

二进制格式

  • 二进制:体积小、速度块、没有歧义
  • HTTP2不在像HTTP1.1一样使用纯文本的报文,而是使用二进制格式,将报文分为头信息帧和数据帧

    • img
  • 对人不友好,但是对计算机友好,可以直接解析二进制报文,增加了数据传输效率
  • 头信息帧的最后4个字节是流标识符,最高位被保留不用,流标识位用于表示该Fream属于哪个Stream,接收方可以根据该信息从乱序的帧中找到相同Stream ID的帧从而有序组装信息

多路复用

  • 为每个请求分配一个唯一的流id,并将请求分成多个块,每个块有头信息帧和数据帧组成,头信息帧中的流标识就是这个块所属请求的流id
  • HTTP2不同的Stream的块是可以乱序发送的,因此可以并发不同的Stream,也就是HTTP2可以并行交错地发送请求和响应
  • 流的特点

    • 流是可并发的,一个HTTP2连接上可以同时发出多个流传输数据
    • 客户端和服务端都可以创建流,客户端发出为奇数,服务器为偶数
    • StreamID不可复用,只能顺序递增,使用完后需要发出控制帧GOAWAY关闭TCP连接
    • 第0号流不能关闭,不能发送数据帧,只能发送控制帧,用于流量控制

优先级

  • 客户端可以指定数据流的优先级

服务端推送

  • HTTP1.1每一个网络资源都必须由客户端明确地请求
  • HTTP2服务器可以主动向客户端发送消息
  • 例如浏览器请求HTML时提前将可能用到的js等静态资源主动发送给客户端减少延时等待与避免请求

HTTP3.0与HTTP2.0的区别

协议

  • HTTP2是基于TCP协议的
  • HTTP3将下层的TCP协议更改为UDP协议并增加了QUIC协议

    • QUIC是一个在UDP上的伪TCP+TLS+HTTP2的多路复用协议

      • Packet Header

        • img
        • Long Packet Header用于首次建立连接
        • Short Packet Header用于日常传输数据

    解决HTTP2队头阻塞问题

    • QUIC为每个流分配唯一的流ID用来表示不同的请求,同时为每个流分配一个独立的滑动窗口,使得一个连接上的多个流之间没有依赖关系,都是相互独立的

    流量控制

    • 通过window_update帧告诉发送方自己可以接收的字节数
    • 通过BlockFrame告诉接收方由于流量控制被阻塞了,无法发送数据
    • QUIC的每个Stream都有自己的滑动串口,不同Stream互相独立
    • 两种级别的流量控制

      • Stream级别

        • 防止单个Stream消耗连接的全部接收缓冲
        • TCP的接收窗口只有在前面所有数据包都接收到了才会移动左边界
        • QUIC接收串口的左边界取决于接收到的最大偏移字节数

          • 可以乱序确认
      • Connection级别

        • 限制连接中所有流相加起来的总字节数,防止发送方超过连接的缓冲容量

    拥塞控制

    • QUIC处于应用层,不需要内核支持,更新比较快,同时还可以针对不用的应用设置不同的拥塞控制算法
    • TCP的拥塞控制需要对所有应用程序都生效,更新较慢

    更快的连接建立

    • HTTP2.0中存在TCP与TLS的握手时延迟:需要经过TCP三次握手和TLS四次握手,共3个RTT时延才能发出请求数据;TCP由于拥塞控制,刚建立连接的TCP会有慢启动过程,对TCP连接产生减速效果

      • TCP和TLS是分层的,分别属于内核实现的传输层、openssl库实现的表示层,难以合并在一起,需要分批次握手
    • HTTP3在传输数据前需要QUIC握手,只需要1RTT,目的是为了确认双方的连接ID;同时QUIC协议内部包含了TLS1.3,只需要1个RTT就可以以同时完成建立连接和密钥协商了

      • img
    • 甚至在第二次连接时应用数据保可以和QUIC握手信息一起发送发到0RTT效果

    连接迁移

    • 基于TCP传输协议的HTTP协议是通过四元组确定一条TCP连接,当设备从一个网络切换到另一个网络的时候IP地址改变了,就需要断开连接重新建立连接
    • QUIC没有使用四元组绑定连接,而是通过连接ID标识通信的两个端点,客户端和服务器各选择一组ID标识自己,因此即使移动设备网络变化导致IP地址变化了,只要仍然有上下文信息(连接ID、TLS密钥等)就可以无缝复用原连接了,消除重连成本