FastAPI 源码阅读==浏览器一次请求到 uvicorn/FastAPI 的底层流程(含 epoll/FD)

浏览器一次请求到 uvicorn/FastAPI 的底层流程(含 epoll/FD)

  1. 浏览器发起 HTTP 请求 → 建立 TCP 连接

浏览器向服务器的:

IP:PORT(例如 1.2.3.4:8080)

发起三次握手,建立 TCP 连接。

  1. uvicorn 在服务器上监听端口

uvicorn(Python 级别)做:

sock = socket()

sock.bind(('0.0.0.0', 8080))

sock.listen()

这一步创建了:

监听 socket(FD),比如 fd=7

随后 uvicorn 会将这个 socket 加入事件循环:

loop.add_reader(fd=7, callback=on_accept)

如果使用 uvloop,该操作最终会变成:

libuv 调用 epoll_ctl(ADD fd=7)

  1. uvloop(libuv)使用 epoll 监听这些 FD

libuv 在 Linux 下:

为事件循环创建一个 epoll 实例

调用 epoll_ctl() 注册 fd=7

进入循环,不停执行:

epoll_wait()

这是关键点:

🔥 内核不会主动"调用回调"

而是:

✔ 内核只是在 epoll 实例里标记:

"某个 FD 已经准备好读/写了"

然后等用户空间 epoll_wait() 返回。

  1. 浏览器发来第一个 HTTP 报文 → FD 可读(EPOLLIN)

当客户端发送 HTTP 请求报文,到达服务器的 fd=9(已 accept 的连接):

内核将 fd 标记为"可读"

放入 epoll 的 ready-list

然后 epoll_wait() 被唤醒并返回

没有任何"内核调用回调"的行为

只有 epoll_wait 主动返回就绪 FD 列表

  1. uvloop 的事件循环得到事件 → 调用对应回调

uvloop 的事件循环不断运行:

epoll_wait() → ready FDs → 调用 Python 层对应回调

例如:

fd=7(监听端口)有 EPOLLIN → on_accept 被调用

fd=9(某个客户端连接)有 EPOLLIN → on_read 被调用

这些回调函数最终进入 uvicorn 的 HTTP 解析逻辑。

  1. HTTP/1.1 Keep-Alive → 同一个 FD 多次进入 ready list

浏览器下一次发请求(仍在同一 TCP 连接上):

内核再次检测到 fd=9 可读

再次将 fd=9 放入 epoll ready-list

uvloop 再次从 epoll_wait 得到它

uvicorn 再次处理(这一次就是第二个 HTTP 请求)

FD 不会关闭

FD 会反复进入 ready-list

直到浏览器或服务器主动关闭连接

⭐ 最终整理后的版本(推荐你保存)

下面是一版简洁 + 完全准确的表述:

✅ 从浏览器发起 HTTP 请求到 uvicorn/FastAPI 的底层机制(含 FD / epoll / uvloop)

浏览器发起 HTTP 请求 → 建立 TCP 连接

浏览器与服务器的监听端口(例如 8080)建立 TCP 连接。

uvicorn 监听端口,创建监听 FD

uvicorn 创建 socket FD(如 fd=7)并调用事件循环注册监听。

uvloop(基于 libuv)将 FD 注册到 epoll

libuv 调用 epoll_ctl(EPOLL_CTL_ADD),将监听 FD 加入 epoll。

事件循环执行 epoll_wait() 等待就绪 FD

内核不会主动调用回调,只会在 epoll 实例中标记就绪 FD。

浏览器发送 HTTP 报文 → FD 可读

内核将该 FD 标记为 EPOLLIN,epoll_wait 被唤醒并返回该 FD。

uvloop 拿到 ready FD → 调用对应的回调函数

对监听 FD → accept 回调

对连接 FD → read 回调(进入 uvicorn HTTP parser)

FastAPI 处理请求并返回响应

Keep-Alive 下:同一个 FD 持续复用

当浏览器再次发起请求,FD 再次可读,被 epoll 标记,再次被 uvloop 回调处理。

连接关闭时,FD 被 epoll 删除并关闭

当浏览器或服务器关闭连接,FD 才真正关闭和消失。

🎯 最终一句话

一次 HTTP 请求不会导致 FD 消失,只要 Keep-Alive 存在,同一个 FD 会多次进入 epoll 的 ready list;只有 TCP 连接断开时 FD 才会被关闭。

相关推荐
BestSongC20 小时前
基于VUE和FastAPI的行人目标检测系统
vue.js·人工智能·yolo·目标检测·fastapi
数据知道1 天前
FastAPI项目:构建打字速度测试网站(MySQL版本)
数据库·python·mysql·fastapi·python项目
A尘埃3 天前
Python后端框架:FastAPI+Django+Flask
python·django·flask·fastapi
q***82914 天前
开源模型应用落地-FastAPI-助力模型交互-进阶篇-中间件(四)
开源·交互·fastapi
小兵张健4 天前
Java + Spring 到 Python + FastAPI (三)
python·spring·fastapi
数据知道4 天前
FastAPI基础项目:仿头条新闻的web项目,实现基本的新闻列表页和详情页查看功能
前端·python·fastapi·python项目
檀越剑指大厂6 天前
【Python系列】fastapi和flask中的阻塞问题
python·flask·fastapi
q***06477 天前
开源模型应用落地-FastAPI-助力模型交互-进阶篇-中间件(四)
开源·交互·fastapi
q***2519 天前
开源模型应用落地-FastAPI-助力模型交互-进阶篇-中间件(四)
开源·交互·fastapi