HTTP相关面试题

HTTP/1.1、HTTP/2、HTTP/3 演变

HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

HTTP/1.1 相⽐ HTTP/1.0 性能上的改进:

  • 使⽤长连接的⽅式改善了 HTTP/1.0 短连接造成的性能开销。
  • ⽀持管道(pipeline)网络传输,只要第⼀个请求发出去了,不必等其回来,就可以发第⼆个请求出去,可以减少整体的响应时间。

但 HTTP/1.1 还是有性能瓶颈:

  • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越⼤。只能压缩 Body 的部 分;
  • 发送冗长的⾸部。每次互相发送相同的⾸部造成的浪费较多;
  • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客⼾端⼀直请求不到数据,也就是 队头阻塞;
  • 没有请求优先级控制;
  • 请求只能从客⼾端开始,服务器只能被动响应。

HTTP/2 做了什么优化?

HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。

那 HTTP/2 相⽐ HTTP/1.1 性能上的改进:

  • 头部压缩
  • ⼆进制格式
  • 并发传输
  • 服务器主动推送资源

头部压缩

HTTP/2 会压缩头 (Header)如果你同时发出多个请求,他们的头是⼀样的或是相似的,那么,协 议会帮你消除重复的部分 。 这就是所谓的 HPACK 算法 :在客⼾端和服务器同时维护⼀张头信息表,所有字段都会存⼊这个 表,⽣成⼀个索引号,以后就不发送同样字段了,只发送索引号,这样就提⾼速度了。

二进制格式

HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式 ,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)

并发传输

我们都知道 HTTP/1.1 的实现是基于请求-响应模型的。同⼀个连接中,HTTP 完成⼀个事务(请求 与响应),才能处理下⼀个事务,也就是说在发出请求等待响应的过程中,是没办法做其他事情 的,如果响应迟迟不来,那么后续的请求是⽆法发送的,也造成了队头阻塞的问题。

⽽ HTTP/2 就很⽜逼了,引出了 Stream 概念,多个 Stream 复⽤在⼀条 TCP 连接。

1 个 TCP 连接包含多个 Stream,Stream ⾥可以包含 1 个或多个 Message, Message 对应 HTTP/1 中的请求或响应,由 HTTP 头部和包体构成。Message ⾥包含⼀条或者多 个 Frame,Frame 是 HTTP/2 最⼩单位,以⼆进制压缩格式存放 HTTP/1 中的内容(头部和包体)。

针对不同的 HTTP 请求用独一无二的 Stream ID 来区分,接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream ,也就是 HTTP/2 可以并行交错地发送请求和响应。

服务器主动推动

HTTP/2 还在⼀定程度上改善了传统的「请求 - 应答」⼯作模式,服务端不再是被动地响应,可以 主动向客⼾端发送消息。

客⼾端和服务器双方都可以建立Stream , Stream ID 也是有区别的,客⼾端建⽴的 Stream 必须 是奇数号 ,⽽服务器建⽴的 Stream 必须是偶数号

HTTP/2 有什么缺陷?

HTTP/2 通过 Stream 的并发能⼒,解决了 HTTP/1 队头阻塞的问题,看似很完美了,但是 HTTP/2 还是存在"队头阻塞"的问题,只不过问题不是在 HTTP 这⼀层⾯,⽽是在 TCP 这⼀层。

HTTP/2 是基于 TCP 协议 来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区⾥的数据返回给 HTTP 应⽤,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区⾥,只有等到这 1 个字节数据到达时, HTTP/2 应⽤层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。

所以,一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来

HTTP/3 做了哪些优化?

前面我们知道了 HTTP/1.1 和 HTTP/2 都有队头阻塞的问题:

  • HTTP/1.1 中的管道( pipeline)虽然解决了请求的队头阻塞,但是没有解决响应的队头阻塞, 因为服务端需要按顺序响应收到的请求,如果服务端处理某个请求消耗的时间⽐较⻓,那么只 能等响应完这个请求后, 才能处理下⼀个请求,这属于 HTTP 层队头阻塞。
  • HTTP/2 虽然通过多个请求复用一个 TCP 连接解决了 HTTP 的队头阻塞 ,但是一旦发生丢包,就会阻塞住所有的 HTTP 请求,这属于 TCP 层队头阻塞。

HTTP/2 队头阻塞的问题是因为 TCP,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP

UDP 发送是不管顺序,也不管丢包的,所以不会出现像 HTTP/2 队头阻塞的问题。⼤家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。

QUIC 有以下 3 个特点。

  • ⽆队头阻塞
  • 更快的连接建⽴
  • 连接迁移

无队头阻塞

QUIC 有⾃⼰的⼀套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他 流不会受到影响,因此不存在队头阻塞问题。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包 丢失了,其他流也会因此受影响。

所以,QUIC 连接上的多个 Stream 之间并没有依赖,都是独⽴的,某个流发⽣丢包了,只会影响 该流,其他流不受影响。

更快的连接建立

对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表⽰层,因此它们难以合并在⼀起,需要分批次来握⼿,先 TCP 握⼿,再 TLS 握⼿。

HTTP/3 在传输数据前虽然需要 QUIC 协议握⼿,但是这个握⼿过程只需要 1 RTT,握⼿的⽬的是 为确认双⽅的「连接 ID」,连接迁移就是基于连接 ID 实现的。

但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,⽽是 QUIC 内部包含了 TLS,它在⾃⼰的帧会携带 TLS ⾥的"记录",再加上 QUIC 使⽤的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建⽴连接与密钥协商。

连接迁移

基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端⼝、⽬的 IP、⽬的端⼝)确定 ⼀条 TCP 连接。

那么当移动设备的网络从流量切换到 WIFI 时,意味着 IP 地址变化了,那么就必须要断开连接,然后重新建⽴连接。⽽建⽴连接的过程包含 TCP 三次握⼿和 TLS 四次握⼿的时延,以及 TCP 慢启动的减速过程,给⽤⼾的感觉就是⽹络突然卡顿了⼀下,因此连接的迁移成本是很⾼的。

⽽ QUIC 协议没有⽤四元组的⽅式来"绑定"连接,⽽是通过连接 ID 来标记通信的两个端点,客⼾ 端和服务器可以各⾃选择⼀组 ID 来标记⾃⼰,因此即使移动设备的⽹络变化后,导致 IP 地址变化 了,只要仍保有上下⽂信息(⽐如连接 ID、TLS 密钥等),就可以"⽆缝"地复⽤原连接,消除重连 的成本,没有丝毫卡顿感,达到了连接迁移的功能。

所以, QUIC 是⼀个在 UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议。

与常用通信协议的区别

HTTP 和 RPC 的区别

TCP 是传输层的协议 ,而基于 TCP 造出来的 HTTP 和各类 RPC 协议,它们都只是定义了不同消息格式的应用层协议而已。

定义

  • HTTP 协议(Hyper Text Transfer Protocol),⼜叫做超⽂本传输协议。我们⽤的⽐较多,平时上⽹在浏览器上敲个⽹址就能访问⽹⻚,这⾥⽤到的就是 HTTP 协议。
  • 而RPC(Remote Procedure Call),⼜叫做远程过程调⽤。它本⾝并不是⼀个具体的协议,⽽是⼀ 种调⽤⽅式。

设计目标

  • HTTP主要用于跨平台、跨语言的交互
  • RPC主要用于内部系统高性能通信

服务发现

服务发现就是确定服务对应的IP和端口

  • 在 HTTP 中,你知道服务的域名,就可以通过 DNS 服务去解析得到它背后的 IP 地址,默认 80 端 ⼝。
  • 而 RPC 的话,就有些区别,⼀般会有专⻔的中间服务去保存服务名和IP信息,⽐如 Consul 或者 Etcd,甚⾄是 Redis。想要访问某个服务,就去这些中间服务去获得 IP 和端⼝信息。由于 DNS 也 是服务发现的⼀种,所以也有基于 DNS 去做服务发现的组件,⽐如CoreDNS。

底层连接形式

  • 以主流的 HTTP/1.1 协议为例,其默认在建⽴底层 TCP 连接之后会⼀直保持这个连接(Keep Alive),之后的请求和响应都会复⽤这条连接。
  • ⽽ RPC 协议,也跟 HTTP 类似,也是通过建⽴ TCP ⻓链接进⾏数据交互,但不同的地⽅在于, RPC 协议⼀般还会再建个连接池 ,在请求量⼤的时候,建⽴多条连接放在池内,要发数据的时候 就从池⾥取⼀条连接出来,**⽤完放回去,下次再复⽤,**可以说⾮常环保。

由于连接池有利于提升网络请求性能,所以不少编程语言的网络库里都会给 HTTP 加个连接池 ,比如 Go 就是这么干的。

传输的内容

  • RPC通常使用二进制协议和高效的序列化格式,性能较高。
  • 由于基于文本协议(HTTP/1.x),性能相对较低,尤其是在高并发场景下。HTTP/2 和 HTTP/3 通过二进制协议和多路复用等技术提升了性能。

HTTP 和 WebSocket 的区别

通信模式

  • HTTP请求-响应模型:客户端发送请求,服务器返回响应,通信是单向的。每次请求都需要建立和关闭连接(HTTP/1.x),或者通过持久连接复用(HTTP/2)。半双工通信。
  • WebSocket全双工通信:客户端和服务器之间建立持久连接,双方可以随时发送消息。通信是双向的,适合实时交互场景。

连接生命周期

  • WebSocket :建立连接后,客户端和服务器可以保持长连接,直到显式关闭。连接建立后,通信开销较低,适合频繁的数据交换。
  • HTTP:在 HTTP/1.x 中,每次请求都需要建立和关闭连接,导致较高的开销。在 HTTP/2 中,支持多路复用,可以在一个连接上并行处理多个请求。

使用场景

  • HTTP:适用于 Web 页面加载、RESTful API、文件传输等场景。适合一次性请求-响应的交互模式。
  • WebSocket:适用于实时通信场景,如在线聊天、实时通知、在线游戏、股票行情等。适合需要频繁双向通信的场景。

协议升级

  • WebSocket 连接的建立需要通过 HTTP 协议进行升级。
  • 客户端发送一个 HTTP 请求,包含 Upgrade: websocket 头部,服务器同意升级后,连接转换为 WebSocket 协议。

SSE(Server-Sent Events)与 HTTP 的区别

定义

  • HTTP(HyperText Transfer Protocol)
    • 是一种应用层协议,主要用于在 Web 浏览器和服务器之间传输超文本(如 HTML)。
    • 基于请求-响应模型,通常使用 TCP 作为传输层协议。
  • SSE(Server-Sent Events)
    • 是一种基于 HTTP 的单向通信机制,允许服务器向客户端推送实时事件。
    • 设计目标是实现服务器到客户端的单向实时通信。

通信模式

  • HTTP
    • 请求-响应模型:客户端发送请求,服务器返回响应,通信是单向的。
    • 每次请求都需要建立和关闭连接(HTTP/1.x),或者通过持久连接复用(HTTP/2)。
  • SSE
    • 单向推送模型:客户端发起连接后,服务器可以持续向客户端推送事件。
    • 通信是单向的,适合服务器向客户端推送实时数据。

3. 连接生命周期

  • HTTP
    • 在 HTTP/1.x 中,每次请求都需要建立和关闭连接,导致较高的开销。
    • 在 HTTP/2 中,支持多路复用,可以在一个连接上并行处理多个请求。
  • SSE
    • 建立连接后,服务器可以持续向客户端推送事件,直到显式关闭。
    • 连接是持久的,适合服务器主动推送数据的场景。
相关推荐
IsToRestart28 分钟前
什么是RPC,和HTTP有什么区别?
网络协议·http·rpc
okok__TXF32 分钟前
Rpc导读
网络·网络协议·rpc
不修×蝙蝠1 小时前
HTTP 协议(Ⅲ)
服务器·http·javaee·http协议
&向上1 小时前
RK3588配置成为路由器
网络·智能路由器·rk3588
猫猫的小茶馆2 小时前
【网络编程】UDP协议
linux·服务器·网络·网络协议·ubuntu·udp
十月ooOO2 小时前
小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统,不需要降级 v1.0.91 (2025)
网络·ssh·路由器·openwrt
SKYDROID云卓小助手2 小时前
无人设备遥控器之如何分享数传篇
网络·人工智能·算法·计算机视觉·电脑
r_martian4 小时前
RPC:分布式系统的通信桥梁
网络·网络协议·rpc
KeLin&4 小时前
ESP32 websocket-client
网络·websocket·网络协议
科技小E5 小时前
EasyRTC:基于WebRTC与P2P技术,开启智能硬件音视频交互的全新时代
网络·网络协议·小程序·webrtc·p2p·智能硬件·视频监控