HTTP/2 如何缓解 HTTP/1.1 阻塞;长连接对 Nginx 有什么影响?

第49题:HTTP/2 如何缓解 HTTP/1.1 阻塞;长连接对 Nginx 有什么影响?

1. 来源边界

原表直接给出的核心结论是:

  • HTTP/2 在单连接上支持多 Stream 多路复用;
  • 使用 Binary Framing;
  • 使用 Header Compression;
  • 能缓解 HTTP/1.1 的应用层 Head-of-Line Blocking;
  • TCP 丢包仍然会影响同一个 HTTP/2 TCP 连接上的多个 Stream;
  • 大量长连接会占用 Nginx Connection、文件描述符和内存;
  • 需要关注 worker_connections
  • 需要调 Keep-Alive / Idle Timeout;
  • 需要关注 Upstream Connection Pool;
  • 需要监控活跃连接、事件循环延迟和连接复用情况。

2. 核心回答

HTTP/1.1 的主要问题在于:同一个 TCP 连接上,请求和响应缺少 HTTP/2 那样的独立 Stream 标识。

HTTP/1.1 虽然支持 Pipelining:

Request A
Request B
Request C

可以连续发送,但服务端仍必须按照:

Response A
Response B
Response C

的顺序返回。

如果:

A = 慢请求

那么:

B / C

即使已经处理完成,也可能受到前一个响应影响。

这属于:

Application-layer Head-of-Line Blocking。

HTTP/2 将每个请求/响应映射成独立 Stream:

TCP Connection
├── Stream 1
├── Stream 3
├── Stream 5
└── Stream 7

不同 Stream 的 Frame 可以交错发送:

S1 DATA
S3 DATA
S1 DATA
S5 DATA
S3 DATA

因此某一个应用层请求慢下来时,其他 Stream 仍然可以继续传输。

但 HTTP/2 底层仍运行在:

TCP

之上。

一旦 TCP 某个 Segment 丢失,TCP 需要按照可靠、有序字节流语义等待丢失数据重传,因此同一连接上的多个 HTTP/2 Stream 都可能受到影响。

所以可以总结成:

HTTP/2:
缓解 HTTP 应用层 HOL

TCP:
仍存在 Transport-layer HOL

3. HTTP/1.1 为什么会有 Head-of-Line Blocking

HTTP/1.1 的一个核心限制是:

同一个连接里的 Response 与 Request 主要依赖顺序关联。

例如:

Client:

GET /slow
GET /small-a
GET /small-b

假设服务器处理时间:

/slow     → 5 s
/small-a  → 10 ms
/small-b  → 10 ms

即使:

small-a
small-b

已经计算完成,Pipelining 下 Response 仍需要保持请求顺序。

所以:

slow
↓
small-a
↓
small-b

产生队头阻塞。


4. HTTP/1.1 为什么常用多个 TCP 连接

为了绕开单连接上的阻塞,HTTP/1.x Client 通常会:

TCP Connection 1 → Request A
TCP Connection 2 → Request B
TCP Connection 3 → Request C
...

这样能够增加并发。

代价是:

  • 更多 TCP Handshake;
  • 更多 TLS Handshake;
  • 更多 Socket;
  • 更多 FD;
  • 更多 Server Connection State;
  • 多条连接分别进行拥塞控制。

因此:

Connections↑ Connections\uparrow Connections

虽然提高并发,但 Server 和 Network Resource 也会上升。


5. HTTP/2 怎么解决这一层问题

HTTP/2 引入:

Stream。

每个请求/响应属于一个:

stream_id stream\_id stream_id

例如:

Stream 1:
GET /slow

Stream 3:
GET /a

Stream 5:
GET /b

它们共享同一个:

TCP Connection

但逻辑上相互独立。

所以可以:

Stream 1 HEADERS
Stream 3 HEADERS
Stream 5 HEADERS

Stream 3 DATA
Stream 5 DATA
Stream 1 DATA
...

这就是:

Multiplexing。


6. Multiplexing 为什么能够降低阻塞

HTTP/1.1 Pipelining 更接近:

Request A
Request B
Request C

↓

Response A
Response B
Response C

HTTP/2 则可以:

A1
B1
C1
B2
A2
C2

其中:

A1/A2

属于 Stream A。

B1/B2

属于 Stream B。

所以:

Slow(StreamA) Slow(Stream_A) Slow(StreamA)

不会在 HTTP 应用层直接要求:

StreamB Stream_B StreamB

等待 A 的完整 Response 发送结束。

RFC 9113 直接将这一能力描述为:

interleaving messages on the same connection

7. Binary Framing 是什么

HTTP/2 的基本协议单位是:

Frame。

常见 Frame 包括:

HEADERS
DATA
SETTINGS
WINDOW_UPDATE
RST_STREAM
GOAWAY

一个 HTTP Message 会被拆成多个 Frame。

例如:

HTTP Response
      ↓
HEADERS Frame
DATA Frame
DATA Frame

每个 Frame 带有:

Stream Identifier

因此接收端可以判断:

这个 Frame 属于哪个请求。

这为 Multiplexing 提供了基础。


8. 为什么 Binary Framing 也有价值

HTTP/1.x 的协议组织高度依赖文本行、Header 边界等规则。

HTTP/2 使用二进制 Frame 后:

  • Frame 类型明确;
  • Length 明确;
  • Stream ID 明确;
  • 协议解析更加结构化;
  • 多 Stream Frame 可以统一调度。

Binary Framing 本身不能消除 TCP HOL。

它主要提供更适合 Multiplexing 的传输结构。


9. HTTP/2 Header Compression 是什么

HTTP 请求经常携带大量重复 Header:

Host
Cookie
User-Agent
Accept
Authorization
...

如果一个页面产生:

N N N

个请求,这些 Header 会重复传输。

HTTP/2 使用:

HPACK

压缩 Header Field。

可以通过:

  • 静态表;
  • 动态表;
  • 索引表示;
  • Huffman Coding;

降低重复 Header 的传输量。

因此:

HeaderBytes↓ HeaderBytes\downarrow HeaderBytes

尤其对大量小请求比较有价值。


10. HTTP/2 是否彻底解决了 Head-of-Line Blocking

没有彻底消除。

需要区分两个层次。

10.1 HTTP 应用层

HTTP/2 Stream Multiplexing 可以缓解:

HTTP/1.1 Response Ordering

导致的 HOL。

10.2 TCP 传输层

HTTP/2 仍建立在一条可靠、有序 TCP Byte Stream 上。

假设 TCP 数据:

Packet 1
Packet 2   ← lost
Packet 3
Packet 4

接收端即使已经收到:

Packet 3
Packet 4

TCP 仍需要等待:

Packet 2 retransmission

以后才能向上层连续交付后续字节。


11. TCP 丢包为什么会影响多个 HTTP/2 Stream

假设:

Packet 1 → Stream A
Packet 2 → Stream B  ← Lost
Packet 3 → Stream C
Packet 4 → Stream A

从 HTTP/2 视角:

A / B / C

是不同 Stream。

从 TCP 视角:

全部是一条有序 Byte Stream。

因此 Packet 2 丢失后,Packet 3 和 Packet 4 对上层的交付会受到 TCP 有序语义影响。

所以:

一个 TCP Connection
+
很多 HTTP/2 Streams

意味着网络丢包可能同时影响很多 Stream。


12. HTTP/3 为什么经常被拿来追问

如果面试官继续追问:

那怎么解决 TCP HOL?

可以回答:

HTTP/3 使用:

QUIC

运行于 UDP 之上,并在 QUIC 内部实现多个独立 Stream。

因此:

Stream A

的数据丢失时,通常不会因为 TCP 的全连接字节流顺序要求阻塞:

Stream B
Stream C

已经完整收到的数据。

所以:

HTTP/2:
解决 HTTP 层 HOL

HTTP/3 / QUIC:
进一步缓解跨 Stream 的传输层 HOL

这个回答作为扩展即可。


13. HTTP/2 是不是连接越少越好

也不能绝对理解。

HTTP/2 使用较少 TCP Connection 可以:

  • 减少 Handshake;
  • 减少 Socket;
  • 提高连接复用;
  • 减少多连接间拥塞竞争。

但单 TCP Connection 也意味着:

Network Loss

的 Failure Domain 更集中。

RFC 9113 也明确说明:

HTTP/2 的实际性能还依赖:

  • Flow Control;
  • Prioritization;
  • Stream Scheduling;
  • TCP 状态;
  • Network Condition。

所以:

HTTP/2 HTTP/2 HTTP/2

并不能保证在所有网络场景中都一定比 HTTP/1.1 快。


14. HTTP/2 还有 Flow Control

HTTP/2 同时具有:

Per-Stream Flow Control

和:

Connection-level Flow Control

主要通过:

WINDOW_UPDATE

实现。

接收端告诉发送端:

当前还允许发送多少 DATA。

如果 Flow Control Window 配置或实现不合理,也可能造成 Stream 进度受限。

因此性能问题不能全部归因于:

HOL

还需要检查:

  • Flow Control;
  • Backend Latency;
  • Stream Scheduling;
  • Packet Loss;
  • Congestion。

15. 接下来为什么会问 Nginx 长连接

HTTP/2 的一个重要特点是:

一条连接持续时间更长
+
同连接承载更多请求

而实际生产环境中 Nginx 经常位于:

Client
↓
Nginx
↓
Upstream

因此需要考虑:

Client Long Connection

和:

Upstream Persistent Connection

两种资源。


16. 长连接会不会一个连接占一个 Nginx 线程

Nginx 采用:

Event-driven + Non-blocking I/O

模型。

一个 Worker 可以处理大量 Socket Event。

因此空闲长连接不会对应:

1 Connection = 1 Thread

这种资源模型。

但每一个连接仍然会持续占用资源,包括:

  • Nginx Connection Structure;
  • File Descriptor;
  • Kernel Socket;
  • Socket Buffer;
  • 一定的 Worker Memory;
  • TLS Connection State;
  • Timer;
  • HTTP/2 State。

所以:

Event Driven

降低了线程成本。

它不会把每连接成本降到零。


17. Nginx 的 worker_connections 是什么

Nginx 官方定义:

worker_connections

表示:

每个 Worker 能同时打开的最大连接数量。

例如:

worker_processes 4;

events {
    worker_connections 4096;
}

粗略来看理论 Connection Slot 数量是:

$$
4\times4096

16384
$$

但这个数字不能直接理解成:

最多 16384 个客户端。

18. 为什么 worker_connections 不能直接等于客户端数

因为 Nginx 官方明确指出:

worker_connections 包含:

  • Client Connection;
  • Proxied Server Connection;
  • 其他连接。

例如一次典型反向代理:

Client
↓ connection 1
Nginx
↓ connection 2
Backend

在请求活跃期间,一个请求可能同时需要:

Client-side Connection
+
Upstream Connection

所以粗略容量关系可以写成:

$$
C_{\text{worker}}

C_{\text{client}}
+
C_{\text{upstream}}
+
C_{\text{other}}
$$


19. 一个简单容量估算

假设:

worker_processes = 8
worker_connections = 8192

理论 Connection Slot:

$$
8\times8192

65536
$$

如果业务主要是反向代理,并且高峰期大多数 Client 同时需要一个 Upstream Connection,可以粗略考虑:

Cclient+Cupstream≈2Cactive request C_{\text{client}} + C_{\text{upstream}} \approx 2C_{\text{active request}} Cclient+Cupstream2Cactive request

因此真正能够承载的活跃 Client 数会明显低于:

65536 65536 65536

同时还需要预留:

  • Idle Keep-Alive;
  • Monitoring;
  • Internal Connection;
  • Graceful Reload 期间旧 Worker 的连接;
  • Upstream Pool。

所以最终容量必须通过压测确定。


20. File Descriptor 为什么很重要

Socket 在 Linux 中对应:

File Descriptor。

所以:

Connections↑⇒FD↑ Connections\uparrow \Rightarrow FD\uparrow Connections↑⇒FD

即使设置:

worker_connections 100000;

如果 OS 对 Worker 的:

RLIMIT_NOFILE

只有:

1024

Nginx 也不可能真正打开 100000 个 Socket。

Nginx 提供:

worker_rlimit_nofile ...

用于调整 Worker 的最大 Open File Limit。

实际还需要检查系统层:

ulimit -n

等限制。


21. 长连接对内存有什么影响

每一个连接都至少会产生:

Connection State
Socket State
Timers
Protocol State

如果启用 TLS,还会增加:

TLS Session State
Buffers

HTTP/2 连接还要维护:

  • Stream State;
  • HPACK State;
  • Flow-control Window;
  • Frame Processing State。

因此可以粗略理解:

Memory≈C×Mper connection+Mrequest+Mcache Memory \approx C \times M_{\text{per connection}} + M_{\text{request}} + M_{\text{cache}} MemoryC×Mper connection+Mrequest+Mcache

其中:

C C C

是并发连接数。

实际每连接占用需要通过目标配置和压测测量。


22. Idle Keep-Alive 为什么也会消耗容量

假设用户请求已经完成。

TCP Connection 保持:

OPEN

等待下一次请求。

此时虽然 CPU 消耗很低,但仍占用:

FD
Connection Slot
Socket
Memory
Timer

Nginx 的 stub_status 中:

Waiting

就是当前等待下一请求的空闲 Client Connection。

因此出现:

Waiting = 100000

说明大量连接正在空闲等待。


23. keepalive_timeout 控制什么

客户端侧:

keepalive_timeout 75s;

表示空闲 Keep-Alive Client Connection 在 Server 端可以保持多久。

如果 Timeout 太长:

Idle Connections ↑
FD ↑
Connection Slots ↑
Memory ↑

如果 Timeout 太短:

Connection Reuse ↓
TCP Handshake ↑
TLS Handshake ↑
Latency ↑

因此它是:

ResourceUsage↔ConnectionReuse ResourceUsage \leftrightarrow ConnectionReuse ResourceUsageConnectionReuse

之间的权衡。


24. keepalive_requests 为什么也重要

Nginx 允许限制:

一个 Keep-Alive Connection 最多处理多少 Request。

当前官方默认:

keepalive_requests 1000

原因之一是:

长期不关闭 Connection 会使某些 Per-connection Memory Allocation 更晚释放。

所以不能简单配置:

keepalive_requests 无限大

希望最大化复用。

需要同时考虑内存释放。


25. keepalive_time 和 keepalive_timeout 有什么区别

可以简单理解:

25.1 keepalive_timeout

关注:

Idle 多久以后关闭。

没有新Request
↓
等待 timeout
↓
Close

25.2 keepalive_time

关注:

这个 Connection 最长允许持续使用多久。

即使一直有 Request:

Request
Request
Request
...

达到最大 Lifetime 后,也会在合适时机关闭。

因此两个参数控制的是不同维度。


26. Upstream Keep-Alive 又是什么

架构:

Client
↓
Nginx
↓
Application Server

Nginx 也可以复用:

Nginx ↔ Backend

之间的 TCP Connection。

否则每个请求都:

connect()
↓
request
↓
response
↓
close()

会不断产生:

  • TCP Handshake;
  • TLS Handshake;
  • Ephemeral Port;
  • Backend Accept Cost。

Upstream Keep-Alive 可以降低这些开销。


27. Upstream Keep-Alive Pool 需要注意什么

Nginx 的:

keepalive N;

在 Upstream Context 中控制:

每个 Worker 最多缓存多少条空闲 Upstream Keep-Alive Connection。

一个非常重要的面试点:

keepalive 32

并不代表:

Nginx 到 Backend 最多只有 32 条连接。

它限制的是:

Idle Cached Connections

总活跃 Upstream Connection 仍可能更高。

如果需要限制 Backend 同时处理的 Active Connection,需要结合:

max_conns

等机制。


28. 2026 年 Nginx Upstream Keep-Alive 有一个版本变化

截至 2026 年:

Nginx 1.29.7 起 HTTP Upstream Keep-Alive 已默认启用。

官方文档当前默认缓存:

32

条空闲 Upstream Connection / Worker。

同时 HTTP Proxy 默认已经使用:

HTTP/1.1

因此很多旧教程中的:

proxy_http_version 1.1;
proxy_set_header Connection "";

对于当前版本已经不再是普遍必需配置。

面试中如果涉及具体版本,应先确认实际部署版本。


29. Upstream Pool 太小会怎样

如果并发很高,Keep-Alive Cache 太小:

大量Backend Connection不能复用

会增加:

  • Connect Rate;
  • TCP Handshake;
  • TLS Handshake;
  • Backend Accept;
  • TIME_WAIT;
  • Latency。

表现可能是:

Connection Reuse Rate ↓
Backend Connect Latency ↑

30. Upstream Pool 太大又会怎样

如果配置很多 Worker:

worker_processes = 16

并且每个 Worker 缓存:

keepalive = 1000

理论空闲 Upstream Connection Cache 可能很大。

Backend 端会看到大量:

Idle Connections

持续消耗:

  • Backend FD;
  • Memory;
  • Socket State。

所以 Upstream Pool 应根据:

  • Worker 数;
  • Backend 数;
  • 并发;
  • Backend Connection Capacity;
  • Connection Reuse Rate;

共同调整。


31. 长连接会怎样影响 Nginx Reload

Nginx Graceful Reload 时:

Old Workers
→ 不再接受新连接
→ 等待已有请求/连接退出

New Workers
→ 开始处理新流量

长生命周期 Connection 会让旧 Worker 存活更久。

因此生产环境还需要考虑:

worker_shutdown_timeout

等 Graceful Shutdown 策略。

这在 WebSocket、SSE、长时间 HTTP/2 Connection 等场景尤其重要。


32. WebSocket/SSE 和普通 Keep-Alive 要区分

“长连接”在面试里可能有不同含义。

32.1 HTTP Keep-Alive

请求完成后连接保持空闲,等待下一请求。

32.2 HTTP/2 Connection

一条 Connection 上长期承载多个 Stream。

32.3 WebSocket

连接建立后持续双向通信。

32.4 SSE

Server 长时间保持 Response 并不断发送事件。

这些场景对:

  • Active Connection;
  • Idle Timeout;
  • Buffer;
  • Upstream;
  • Graceful Shutdown;

影响不同。

面试时最好先说明自己讨论的是哪一种。


33. 怎么监控 Nginx 长连接

开源 Nginx 的 stub_status 可以提供:

Active connections
Reading
Writing
Waiting
accepts
handled
requests

其中:

33.1 Active Connections

当前 Client Connection 总量,包括 Waiting。

33.2 Reading

当前正在读取 Request Header 的连接。

33.3 Writing

当前正在向 Client 返回 Response 的连接。

33.4 Waiting

当前等待下一 Request 的 Idle Keep-Alive Client Connection。

如果:

Waiting / Active

长期非常高,可以检查 Keep-Alive 策略是否过于激进。


34. 为什么 accepts 和 handled 也值得看

Nginx 官方指出:

正常情况下:

accepts ≈ handled

如果:

handled < accepts

可能表示出现资源限制。

例如:

worker_connections

达到上限。

所以容量压测时可以同时观察:

accepts−handled accepts-handled acceptshandled


35. 除连接数之外还需要看哪些指标

我会同时观察:

Active Connections
Idle / Waiting Connections
FD Usage
Worker Memory
CPU
Network Throughput
TLS Handshake Rate
Upstream Active Connections
Upstream Keepalive Connections
Backend Connect Time
Request Latency
P95 / P99
5xx
Connection Reset
Timeout

如果系统支持进一步的 Event Loop 指标,也可以监控:

Event-loop Delay / Stall

但这一项需要具体监控实现提供,不能仅靠 stub_status 得到。


36. 一个常见容量估算思路

假设:

100000 Client Connections

其中:

90000 Idle
10000 Active

假设 Active Request 基本都需要 Backend:

10000 Upstream Connections

粗略 Connection 数量已经达到:

100000+10000=110000 100000+10000=110000 100000+10000=110000

还没有计算其他内部资源。

如果有:

worker_processes=8

平均每 Worker:

$$
110000/8

13750
$$

个 Connection。

那么:

worker_connections = 4096

显然不足。

这只是容量估算。

最终仍然需要真实压测确认 Worker 分布、Connection Reuse 和 Memory。


37. 怎么做压测验证

我不会只改:

worker_connections 100000;

然后认为系统支持 10 万连接。

会做分级压测。

37.1 Connection Ramp

例如:

1k
5k
10k
20k
50k
100k

逐级增加。

37.2 每一级观察

记录:

  • Connection Success Rate;
  • P50/P95/P99;
  • FD;
  • Memory;
  • CPU;
  • Waiting;
  • Backend Connections;
  • Error Rate。

37.3 找 Saturation Point

例如当:

50k → 60k

时:

Latency suddenly rises
handled < accepts
5xx increases

说明系统正在接近资源瓶颈。


38. 一个很重要的反例:HTTP/2 一条 TCP 连接可以有很多请求

所以看到:

HTTP/2 Client Connections = 1000

不能推出:

Concurrent Requests = 1000

一条 Connection 可以存在多个 Concurrent Stream。

容量模型要区分:

Physical TCP Connections

和:

Concurrent HTTP Requests / Streams

这也是 HTTP/2 与 HTTP/1.1 容量分析的重要区别。


39. limit_conn 在 HTTP/2 下也要注意语义

Nginx 的 limit_conn 官方文档特别说明:

在 HTTP/2 / HTTP/3 中,每个并发 Request 会被这个模块视作一个独立的 Connection 进行计数。

因此:

limit_conn

的业务限制语义不能简单等同于:

真实TCP连接数量。

做 HTTP/2 限流时需要确认使用的指标到底是:

  • Physical Connection;
  • Concurrent Stream;
  • Request;
  • User;
  • IP。

40. 面试官如果问“HTTP/2 为什么通常更快”

可以回答:

HTTP/2 的核心提升之一是 Multiplexing。HTTP/1.1 Pipelining 要求响应按照请求顺序返回,所以前面的慢响应会产生应用层 Head-of-Line Blocking。HTTP/2 给每个请求建立独立 Stream,再把 HEADERS、DATA 等 Frame 在同一个 TCP Connection 上交错传输,所以慢 Stream 不会在 HTTP 层直接卡住其他 Stream。

同时 HTTP/2 使用 Binary Framing 和 HPACK Header Compression,可以降低协议和重复 Header 开销,也减少了 HTTP/1.x 为并发而建立多条 TCP Connection 的需求。

但 HTTP/2 仍运行在 TCP 上,所以 TCP Segment 丢失时,同一 TCP Connection 上的多个 Stream 仍可能受到 Transport-layer HOL 影响。


41. 面试官如果问“长连接是不是越多越好”

可以回答:

长连接可以降低 TCP/TLS Handshake 和建连开销,提高连接复用率,但它会长期占用 Nginx Connection Slot、FD、Socket 和一定内存,所以需要在复用收益和资源占用之间平衡。

Nginx 使用 Event-driven Non-blocking I/O,一个空闲长连接不会对应一个独立线程,因此它非常适合高并发连接。但 worker_connections 仍限制每个 Worker 能打开的总连接数,而且这里还包括到 Upstream 的连接,同时受 RLIMIT_NOFILE 约束。

我会结合 keepalive_timeoutkeepalive_requests、Upstream Keepalive Pool、Worker Connection 和 FD Limit 调优,并通过 Active/Waiting Connection、FD、内存、P99、Backend Connect Time 和 Connection Reuse 等指标进行压测验证。


42. 面试时可以压缩成下面这段

HTTP/1.1 Pipelining 虽然允许在同一 TCP Connection 连续发送多个请求,但响应仍然必须按请求顺序返回,所以前面的慢请求会造成应用层 Head-of-Line Blocking。

HTTP/2 为每个 Request/Response 建立独立 Stream,并使用 Binary Frame。不同 Stream 的 Frame 可以在同一 TCP Connection 上交错发送,因此一个慢 Stream 不会在 HTTP 层阻止其他 Stream 继续传输。同时 HTTP/2 使用 HPACK 压缩重复 Header,可以降低协议开销,也减少了 HTTP/1.x 为并发而建立大量 TCP Connection 的需求。

但是 HTTP/2 底层仍然是 TCP。TCP 提供可靠、有序的字节流,所以一个 Segment 丢失后,后续数据需要等待重传,同一个 HTTP/2 Connection 上的多个 Stream 仍可能受到 TCP 层 Head-of-Line Blocking 影响。

长连接对 Nginx 的影响主要是 Connection Slot、File Descriptor、Socket/TLS State 和 Memory。Nginx 本身是 Event-driven Non-blocking 架构,所以一条空闲连接不会占一个线程,但资源占用仍然存在。worker_connections 是每个 Worker 的总连接上限,而且 Client 和 Upstream Connection 都会占这个额度,实际还受 RLIMIT_NOFILE 限制。

调优时我会关注 worker_connections、FD Limit、keepalive_timeoutkeepalive_requests 和 Upstream Keepalive Pool,同时监控 Active、Waiting、FD、Memory、P95/P99、Backend Connect Time 和 Connection Reuse Rate。

一句话总结:

HTTP/2 用 Stream Multiplexing 缓解 HTTP 应用层队头阻塞,但 TCP 层 HOL 仍存在;Nginx 的事件驱动模型适合长连接,但长连接仍会持续消耗 Connection、FD 和内存,因此必须做容量规划、超时控制和连接池调优。


43. 当前资料能够确定到什么程度

43.1 原表直接支持

原表明确支持:

  • HTTP/2 单连接多路复用;
  • Binary Framing;
  • Header Compression;
  • 缓解 HTTP/1.1 应用层 HOL;
  • TCP 丢包仍影响同连接多个 Stream;
  • 长连接占用 Nginx Connection;
  • 长连接占用 FD;
  • 长连接占用内存;
  • 调整 worker_connections
  • 调整 Keep-Alive / Idle Timeout;
  • 调整 Upstream Connection Pool;
  • 监控 Active Connections;
  • 监控 Event-loop Delay;
  • 监控 Connection Reuse Rate。

43.2 外部资料补充

本次外部核验进一步补充:

  • HTTP/1.1 Pipelining 的响应顺序要求;
  • HTTP/2 Stream 和 Frame 的正式定义;
  • HPACK;
  • HTTP/2 Flow Control;
  • worker_connections 同时计算 Client 和 Upstream;
  • RLIMIT_NOFILE
  • Nginx Event-driven Worker 模型;
  • keepalive_requests
  • keepalive_time
  • keepalive_timeout
  • Upstream Keepalive Cache 的确切语义;
  • Nginx 1.29.7 的 Upstream Keep-Alive 默认行为变化;
  • stub_status 的 Active / Reading / Writing / Waiting;
  • HTTP/2 下 limit_conn 的特殊计数语义。

44. 来源

  1. 原始题目表,第49题(T5):HTTP/2 如何缓解 HTTP/1.1 阻塞;长连接对 Nginx 影响。
  2. RFC 9112 — HTTP/1.1:定义 HTTP/1.1 Pipelining 和响应顺序规则,并讨论 Head-of-Line Blocking 与多连接。
  3. RFC 9113 — HTTP/2:定义 Stream、Multiplexing、Binary Framing 和 Flow Control,并明确 TCP Head-of-Line Blocking 仍然存在。
  4. RFC 7541 — HPACK: Header Compression for HTTP/2:定义 HTTP/2 Header Compression。
  5. Nginx Core Documentation — worker_connections / worker_rlimit_nofile:定义单 Worker 连接上限,并明确 Upstream Connection 同样计入。
  6. Nginx HTTP Core Module — keepalive_requests / keepalive_time / keepalive_timeout:定义客户端持久连接生命周期和资源释放策略。
  7. Nginx Upstream Module — keepalive / max_conns:定义 Upstream Idle Keepalive Cache 与 Active Connection Limit 的区别。
  8. Nginx stub_status Module:定义 Active、Reading、Writing、Waiting 等 Connection 指标。
  9. Nginx Architecture Documentation:说明 Worker 使用 Non-blocking Event-driven 模型处理大量连接。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白羊丨

开始面试题与解析

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值