一个 HTTP 请求的并发链路:从 Web Server 到 MySQL

一个 HTTP 请求的并发链路:从 Web Server 到 MySQL 前面的文章分别讨论了并发是什么、进程线程协程如何执行请求、IO 多路复用如何管理大量连接,以及如何用 QPS、并发数和响应时间衡量系统。 但这些概念真正进入后端系统之后,会形成一条完整的链路: Client ↓ Web Server / Nginx ↓ Application ↓ Process / Thread / Coroutine ↓ Redis / RPC / MySQL ↓ Response ↓ Client 真正的高并发问题,通常也不是发生在某一个组件上,而是发生在整个链路的容量不匹配上。 例如: Web Server 可以接收 10000 个连接,应用可以运行 1000 个协程,但 MySQL 连接池只有 50 个连接。 这并不意味着系统只能处理 50 个 HTTP 请求,但意味着同时进行数据库操作的请求最多受到这 50 个连接的约束。 因此,理解高并发,不能只看 Web Server 或应用服务器,而要沿着一次请求完整地看下去。 1. 一个 HTTP 请求到底经过哪些组件? 假设用户访问: GET /api/orders/10001 一个典型后端系统可能经过: ┌──────────┐ │ Client │ └────┬─────┘ │ HTTP ▼ ┌──────────────┐ │ Nginx / Web │ │ Server │ └──────┬───────┘ │ ▼ ┌──────────────────┐ │ Application │ │ Hyperf / Java....

2024年07月10日 · 5 min · Leanku

IO 多路复用:一个线程为什么可以同时处理大量 HTTP 请求?

IO 多路复用:一个线程为什么可以同时处理大量 HTTP 请求? 我们知道,一个 Web 服务同时面对大量 HTTP 请求时,并不一定需要: 1000 个请求 ↓ 1000 个线程 对于 IO 密集型服务,更常见的做法是让执行单元在等待网络 IO 时不要一直阻塞,然后利用事件机制处理其他连接。 这就引出了一个非常重要的概念: IO 多路复用(I/O Multiplexing)。 它是理解 Linux 网络服务器、Nginx、Node.js、Swoole、Hyperf 等高并发网络程序的基础。 1. 先从一个 Socket 开始 一个 HTTP 服务器,本质上需要处理大量网络连接。 例如服务器监听: 0.0.0.0:80 客户端建立 TCP 连接后,操作系统会为连接提供对应的 Socket。 可以简单理解为: Client A ─── Socket A ──┐ Client B ─── Socket B ──┤ Client C ─── Socket C ──┤ Client D ─── Socket D ──┤ ▼ Web Server 假设现在有: 10000 个 TCP 连接 服务器需要解决一个问题:...

2024年06月20日 · 6 min · Leanku

进程、线程、协程:后端服务到底是怎么处理并发请求的?

进程、线程、协程:后端服务到底是怎么处理并发请求的? 在上一篇 《理解并发:一个 HTTP 请求到后端到底发生了什么?》 我们从一个 HTTP 请求出发,理解了并发最基本的概念: HTTP 请求 ↓ Web Server ↓ 后端服务 ↓ CPU / IO ↓ MySQL / Redis / RPC ↓ HTTP 响应 但这里留下了一个非常重要的问题: 后端服务到底由谁来执行这些请求? 如果同时来了 1000 个 HTTP 请求,服务器是不是创建 1000 个进程? 如果不是,是不是创建 1000 个线程? 如果也不是,那么一个线程又是怎么处理大量请求的? 要回答这些问题,就必须理解后端程序最核心的三个执行概念: 进程 线程 协程 1. 先建立一个整体认识 可以先把三者理解成三个不同层次的概念: 进程 │ ├── 线程 │ │ │ ├── 协程 │ ├── 协程 │ └── 协程 │ └── 线程 但这里有一个需要特别注意的地方: 协程并不是操作系统进程或线程的同级概念。 进程和线程主要属于操作系统调度与资源管理层面;协程通常是由运行时、语言、框架或用户态库提供的更轻量级执行机制。 因此:...

2024年06月17日 · 5 min · Leanku

理解并发:一个 HTTP 请求到后端到底发生了什么?

理解并发:一个 HTTP 请求到后端到底发生了什么? 在开发后端系统时,我们经常会看到这样的描述: “这个接口支持 1000 并发。” 但“1000 并发”到底意味着什么? 是不是意味着服务器同时启动 1000 个线程? 是不是意味着 CPU 同时执行 1000 个请求? 如果一个请求正在等待 MySQL,CPU 又在做什么? 一个 PHP/Hyperf 服务为什么可以同时处理大量 HTTP 请求? 要真正理解高并发,不能一开始就从 QPS、限流、缓存这些概念入手,而应该先理解一个最基本的问题: 一个 HTTP 请求进入后端以后,到底发生了什么? 1. 先理解什么是并发 并发(Concurrency)描述的是: 多个任务在同一个时间段内处于进行状态,并且它们的执行过程存在交错。 并发和并行(Parallelism)不是同一个概念。 例如: 任务 A:████████ 任务 B: ████████ 两个任务都在进行,但可能只有一个 CPU 核心。 CPU 可以先执行 A: A A A A 然后因为 A 正在等待 IO,转而执行 B: A A → 等待 ↓ B B B B 这属于并发。 如果机器有多个 CPU 核心: CPU Core 1:A A A A CPU Core 2:B B B B 两个任务可以在同一时刻真正执行,这才是并行。...

2024年06月10日 · 5 min · Leanku