[WebServer/Python] uvicorn : Python 高性能 ASGI 服务器

0 序

  • Python uvicorn 的快速入门笔记文档。Uvicorn 是一个超快的 ASGI 服务器,基于 uvloophttptools 构建。

1 概述:uvicorn —— Python 高性能 ASGI 服务器 ≈ Java 的 Tomcat/Netty

产品介绍

  • 产品定位:Uvicorn 是一个为 Python 打造的 ASGI(Asynchronous Server Gateway Interface,异步服务器网关接口)Web 服务器,官方标语是 "The lightning-fast ASGI server"(闪电级 ASGI 服务器)。

它承担 Web 应用与网络之间的“服务器”角色,与 FastAPI(类比Java的Spring Boot Web Starter)、Starlette(类比Java的Spring Web) 等 ASGI 应用框架配合使用,类似 WSGI 时代的 Gunicorn/uWSGI。

  • 诞生的背景与原因:在 Uvicorn 出现之前,Python 一直缺少一个面向异步框架的“低层服务器/应用接口”。传统 WSGI 是同步单调用模型,一个请求一个响应,难以支撑 WebSocket、长轮询等长连接与高并发 I/O 场景。ASGI 规范填补了这一空白,而 Uvicorn 是该规范下最早、最流行的服务器实现之一。

  • 解决的核心问题

    • 异步 Web 框架提供高性能、低延迟的运行时;
    • 原生支持 HTTP/1.1 与 WebSocket 长连接;
    • 通过事件循环(asyncio/uvloop)+ 高性能 HTTP 解析器(h11/httptools)突破【传统同步服务器】的吞吐瓶颈;
    • 提供开箱即用的开发热重载、多 Worker、TLS、代理头解析等运维能力
  • URLs

  • 开源协议:BSD-3-Clause。

  • 作者与维护:由 Tom Christie(Django REST Framework、Starlette 的创造者)创建,隶属于 Encode 开源家族;现由 Marcelo Trylesinski(GitHub 昵称 Kludex) 担任主要维护者,仓库已迁移至 Kludex/uvicorn

发展历程

时间 里程碑
2016 ASGI 规范在 Django Channels 背景下由 Andrew Godwin 提出(异步事件驱动设计,精神续承 WSGI)
2017-05-31 Uvicorn 仓库在 GitHub 创建(encode/uvicorn
2017-06-05 首个 PyPI 版本 0.0.1 发布
2017-11-28 ASGI 2.0 规范发布(脱离 Channel Layer 的通用规范)
2019-03-04 ASGI 3.0 规范发布(改为单可调用 app(scope, receive, send) 风格,沿用至今)
2019-12 Django 3.0 正式支持 ASGI,加速 ASGI 生态普及
2018–2021 伴随 FastAPI 崛起,Uvicorn 成为其默认/首选服务器,Star 与下载量高速增长
2022–2025 保持高频发版节奏;uvicorn.workers 模块宣布弃用,迁移至独立包 uvicorn-worker
2026 仓库由 encode/uvicorn 迁移至 Kludex/uvicorn;截至 2026-08-19 最新版 v0.52.4,累计 202 个 PyPI 版本

说明:上表“2016 提出 ASGI”源自 FastAPI 社区对 ASGI 历史的梳理,ASGI 规范文本以 2.0/3.0 两个正式版本为准。

主要功能

  • ASGI 3.0 接口app(scope, receive, send) 单可调用模型,兼容 ASGI2/WSGI(通过 --interface 切换,WSGI 模式可运行 Flask/Django 等同步应用)。

  • HTTP/1.1 与 Keep-Alive:支持 keep-alive 超时、分块传输、慢速请求背压等。

  • WebSocket:完整支持 WebSocket 长连接(websockets / wsproto 双实现,可配置消息大小、队列、心跳 ping/pong、per-message-deflate 压缩)。

  • Lifespan 生命周期协议:启动/关闭事件(startup/shutdown),供应用初始化/释放资源。

  • 高性能可插拔实现

    • 事件循环:asyncio(纯 Python)或 uvloop(Cython/libuv,更快);
    • HTTP 解析:h11(纯 Python)或 httptools(C 扩展,Node.js 同款解析器)。
  • 开发热重载--reload(基于 watchfiles),支持目录/包含/排除规则与延迟。

  • 多 Worker 进程--workers N,基于 spawn(非 pre-fork),Windows 上也可用;支持优雅重启、SIGHUP 滚动重启、SIGTTIN/SIGTTOU 动态增减 Worker(Unix)。

  • TLS/HTTPS--ssl-keyfile / --ssl-certfile 等原生 SSL 参数。

  • 代理友好--proxy-headers 解析 X-Forwarded-For/X-Forwarded-Proto--forwarded-allow-ips 可信来源白名单,--root-path 子路径挂载。

  • 运维控制:并发上限(--limit-concurrency,超限返回 503)、最大请求数(--limit-max-requests)、keep-alive 超时、优雅停机超时、worker 健康检查超时、backlog。

  • 配置化:命令行、uvicorn.run()uvicorn.Config+uvicorn.Server.env 环境文件、--log-config(.ini/.json/.yaml 日志配置)、自定义响应头。

  • Gunicorn Worker 集成uvicorn.workers.UvicornWorker(已弃用,建议改用 uvicorn-worker 包),将 Uvicorn 性能与 Gunicorn 进程管理结合。

核心优势

  • 高性能uvloop + httptools 组合使其在纯 Python ASGI 服务器中吞吐领先。

社区基准(Talk Python,2025)中 Uvicorn+httptools 约 34k RPS(GET,c128),同环境下 Hypercorn 约 4.9k RPS;自述相对普通 asyncio 事件循环可带来数倍吞吐提升(12k→28k RPS 量级)。

  • 异步原生、长连接能力强:WebSocket、SSE、长轮询天然支持,适合高并发 I/O 密集场景。
  • 生态默认之选:FastAPI、Starlette、Litestar 等主流异步框架的默认/推荐服务器,社区支持、文档、教程沉淀最厚。
  • 轻量与易用:内存占用低(约 15–25MB/worker),pip install 即用,CLI 与程序化 API 双通道,学习成本低。
  • 开发体验好--reload 热重载、彩色日志、访问日志开箱即用。
  • 运维能力较完整:多 Worker、TLS、代理头、并发限制、优雅停机、与 Gunicorn/Nginx/Supervisor 的成熟组合方案。
  • 跨平台:spawn 式多进程让 Windows 也能多 Worker 运行(区别于依赖 fork 的方案)。

主要短板

  • 不支持 HTTP/2 与 HTTP/3:Uvicorn 只支持 HTTP/1.1 与 WebSocket。需要 HTTP/2/3 时只能换 Hypercorn 或 Granian 等服务器。
  • 单事件循环、受 GIL 约束:单进程单事件循环,CPU 密集计算会阻塞事件循环(即便用线程池也受 GIL 限制),需依赖多 Worker 或异步化改造。
  • 进程管理能力弱于 Gunicorn:内置 --workers 只是“能用”,成熟的预分叉、动态扩容、精细信号控制仍建议交给 Gunicorn 等进程管理器。
  • uvicorn.workers 弃用:历史接口逐步迁移至 uvicorn-worker,旧代码需调整。
  • TLS 终止一般交给反向代理:虽支持原生 SSL,官方仍推荐自建部署时用 Nginx/CDN 承担 HTTPS 与 DDoS 防护,直接暴露 TLS 场景较少。
  • 部分组件兼容性uvloop 与某些依赖特定事件循环的库(如 Jupyter)不兼容,需显式 --loop asynciohttptools 为 C 扩展,在无编译环境的受限平台可能退化到纯 Python 实现。

局限性

  • 协议覆盖仅限 HTTP/1.1 + WebSocket,无法满足 HTTP/2 多路复用、HTTP/3/QUIC 等进阶协议需求;
  • 单进程模型下 CPU 密集负载需要自行设计 Worker 规模与任务卸载(如 Celery);
  • 进程级隔离、资源限制、动态扩缩容等企业级进程治理需外部进程管理器配合;
  • 在部分 Windows/受限环境中,Unix socket(--uds)、信号管理(SIGHUP 等)等功能不可用。

适用场景

  • FastAPI / Starlette / Litestar 等异步 API 服务(开发与中小规模生产);
  • WebSocket 实时应用:聊天、实时通知、协作编辑、在线游戏、数据推送;
  • SSE / 长轮询流式接口(含 AI 应用如 MCP Streamable HTTP、LLM 流式输出);
  • 高并发 I/O 密集的异步微服务;
  • Django 3.0+ 的异步应用(配合 Daphne 之外的第二选择);
  • 开发环境热重载调试、CI/测试环境轻量启动;
  • 与 Gunicorn + Nginx/CDN 组合的生产部署(互联网规模服务)。

同类竞品

服务器 语言/运行方式 协议支持 接口 定位与特点
Uvicorn Python(asyncio/uvloop) HTTP/1.1、WebSocket ASGI(可兼容 WSGI) FastAPI/Starlette 默认之选,生态与性能兼顾
Daphne Python(Twisted) HTTP/1.1、HTTP/2、WebSocket ASGI 首个 ASGI 服务器,为 Django Channels 而生,生产广泛使用
Hypercorn Python(asyncio/trio) HTTP/1.1、HTTP/2、HTTP/3、WebSocket ASGI、WSGI 协议覆盖最全,Quart 生态,支持 trio
Granian Rust HTTP/1.1、HTTP/2、WebSocket ASGI、WSGI、RSGI 新兴高性能服务器,低延迟低内存,正被部分项目采用
Gunicorn Python (WSGI 为主) WSGI 成熟进程管理器,常用作 Uvicorn 的“外壳”
uWSGI C HTTP/1.0/1.1 WSGI 等 老牌高吞吐 WSGI 服务器
Mangum Python ASGI 适配器 让 ASGI 应用跑在 AWS Lambda/API Gateway 上

发展趋势

  • 社区活跃度(数据截至 2026-09-04,来自 GitHub API / PyPI):
    • GitHub Star ≈ 10,940Fork ≈ 1,023、Open Issues ≈ 88;
    • 855k 个公开仓库依赖(GitHub “Used by”);
    • PyPI 累计下载量约 63.2 亿次,近期单日下载稳定在 1500 万~1700 万(2026-09-03 单日约 1718 万);
    • 发版节奏活跃:2026 年 4 月至 8 月已连续发布 0.44→0.52.4 多个版本,平均每月 1–3 个版本。
  • Star/Fork 趋势一句话:从 2017 年起步、2019 年后随 FastAPI 生态快速爬升,现处于高度成熟稳定期——增长放缓但依赖面(855k 仓库)与下载量仍在持续扩大,属于“事实标准”型基础设施。
  • 项目发展趋势总结:Uvicorn 已从“新兴性能服务器”演进为 Python 异步 Web 的事实默认服务器,短期不会动摇;其协议短板(HTTP/2/3)由 Hypercorn、Granian 等竞争者补位,长期看 Uvicorn 的护城河在于生态默认地位、稳定性与持续维护,而非协议前沿性。

2 工作原理与架构

概念术语

术语 含义
ASGI Asynchronous Server Gateway Interface,异步服务器网关接口;连接 Python 异步 Web 应用与服务器的标准规范。
Scope ASGI 请求上下文字典,描述连接类型(http/websocket/lifespan)、协议、路径、查询参数、头等。
Receive 应用侧协程,用于接收服务器推送的请求事件(如 http.request)。
Send 应用侧协程,用于把响应事件(如 http.response.starthttp.response.body)发给服务器。
Lifespan ASGI 生命周期协议,服务器在启动/关闭时向应用发送 lifespan.startup/lifespan.shutdown 事件。
uvloop 基于 libuv 的 Cython 事件循环实现,比纯 asyncio 更快。
httptools 源自 Node.js 的 C 语言 HTTP 解析器(Cython 封装),比纯 Python 解析更快。
h11 纯 Python 的 HTTP/1.1 协议实现。
wsproto / websockets WebSocket 协议的两种实现(前者纯 Python 协议库,后者成熟 WebSocket 库)。
Worker 独立进程的服务实例,用于多进程横向扩展。
背压(Backpressure) 服务器在应用处理不过来时,通过缓冲区/排队/断开等手段反压客户端,防止内存被打爆。

架构与运行原理

Uvicorn 是分层可插拔架构:Config 持有全部配置 → Server 负责连接与进程生命周期 → Protocol 层负责协议解析(HTTP/WebSocket)→ Loop 层提供事件循环 → 最终把请求转换为 ASGI 调用交给应用。

flowchart TB subgraph CLI["入口层"] CMD["uvicorn 命令 / uvicorn.run()"] end subgraph CFG["配置层"] Config["uvicorn.Config<br/>(host/port/loop/http/ws/workers/ssl/日志…)"] end subgraph SVC["服务层"] Server["uvicorn.Server<br/>(监听 socket、连接生命周期、优雅停机)"] Supervisor["supervisors/<br/>multiprocess / statreload / watchfilesreload"] Worker["workers.py<br/>(Gunicorn worker 适配)"] end subgraph LOOP["事件循环层(loops/)"] Loop["auto → uvloop / asyncio"] end subgraph PROTO["协议层(protocols/)"] HTTP["HTTP:httptools / h11"] WS["WebSocket:websockets / wsproto"] LS["lifespan:auto/on/off"] end subgraph MID["中间件层(middleware/)"] MW["proxy_headers / asgi2 / wsgi / message_logger"] end subgraph APP["应用层"] App["ASGI 应用 app(scope, receive, send)<br/>(FastAPI / Starlette / Django async…)"] end CMD --> Config --> Server Server --> Supervisor Server --> Worker Server --> Loop Server --> PROTO PROTO --> MID --> App Server --> LS

运行原理要点

  1. 启动Config 汇总 CLI/代码配置,Server.run() 创建事件循环,绑定 socket(host:port 或 Unix socket/fd),按 --workers 派生多个子进程(spawn 方式)。
  2. 协议解析:每个连接由对应 Protocol 类接管——HTTP 用 httptools(C 扩展,快)或 h11(纯 Python),WebSocket 用 websocketswsproto
  3. ASGI 调用:解析出请求后,构造 scope 字典,调用 app(scope, receive, send);应用通过 receive 拉取请求体,通过 send 推送响应事件。Uvicorn 采用 反向控制流(Pull-based):由应用主动 await 事件,而不是服务器强推,从而天然支持背压。
  4. 长连接:WebSocket 连接建立后,应用与客户端通过消息事件双向收发,服务器负责 ping/pong、队列与消息大小控制。
  5. 生命周期:启动时发送 lifespan.startup,停止时发送 lifespan.shutdown,让应用安全初始化/释放资源。
  6. 运维行为:支持 keep-alive 超时、并发上限(超限 503)、优雅停机、代理头注入(X-Forwarded-For/Proto)、请求数上限等。

源码模块结构

当前 main 分支 (2026-09)

uvicorn/
├── main.py            # CLI 入口 / uvicorn.run()
├── config.py          # 配置模型(全部运行参数)
├── server.py          # Server 核心:监听、连接、生命周期、优雅停机
├── importer.py        # 应用导入(字符串路径 → ASGI app)
├── logging.py         # 访问/错误日志与彩色输出
├── workers.py         # Gunicorn worker 类(弃用中)
├── lifespan/          # on.py / off.py / auto.py
├── loops/             # auto.py / asyncio.py / uvloop.py
├── protocols/
│   ├── http/          # h11_impl.py / httptools_impl.py / flow_control.py
│   └── websockets/    # websockets_impl.py / websockets_sansio_impl.py / wsproto_impl.py
├── middleware/        # proxy_headers.py / asgi2.py / wsgi.py / message_logger.py
├── supervisors/       # multiprocess.py / statreload.py / watchfilesreload.py
├── _subprocess.py     # 子进程与信号管理
└── _compat.py / _ansi.py / _types.py

3 使用指南

安装

# 基础安装
pip install uvicorn

# 包含标准依赖(推荐)
pip install "uvicorn[standard]"

# 使用 uv 安装
uv add uvicorn

基本用法

1. 命令行启动

# 基本启动
uvicorn main:app

# 常用参数
uvicorn main:app --host 0.0.0.0 --port 8000 --reload

2. 最小示例 (main.py)

async def app(scope, receive, send): #`async def` 声明一个异步函数(协程函数)。调用它返回一个协程对象,需用 `await` 或事件循环驱动才会执行。这是 【ASGI 应用】的标准签名:`scope`(请求元数据字典)、`receive`(接收消息的异步可调用)、`send`(发送消息的异步可调用)。
    """最简 ASGI 应用"""
    assert scope['type'] == 'http' # `assert` 断言:若 `scope['type']` 不是 `'http'`,抛出 `AssertionError`。作用:【防御性校验】,确保该应用只处理 HTTP 请求(ASGI 还支持 websocket、lifespan 等类型)
    
    await send({ # `await` 等待 `send` 这个【异步可调用】完成。
        'type': 'http.response.start', # 发送 `http.response.start` 消息:状态码 200,响应头 `content-type: text/plain`。这对应 HTTP 响应的起始行 + 头部。
        'status': 200,
        'headers': [[b'content-type', b'text/plain']],
    })
    await send({ # 再次 `await send`,发送 `http.response.body` 消息,响应体为字节 `b'Hello, Uvicorn!'`。 两次 `send` 调用必须按顺序 `await`,保证先写头再写体。
        'type': 'http.response.body',
        'body': b'Hello, Uvicorn!',
    })

这个文件是一个最小 ASGI 应用 ——async def 定义协程入口,assert 校验请求类型,两次 await send 按序写出 HTTP 响应头和响应体。用 uvicorn main:app 命令即可启动。

  • 推荐文献

3. 配合 FastAPI 使用(最常用)

from fastapi import FastAPI # 从 `fastapi` 包导入 `FastAPI` 类。它是整个应用的【核心入口类】,内部封装了 ASGI 应用、路由注册、依赖注入、参数校验、OpenAPI 文档生成等能力。

app = FastAPI() # 实例化一个 FastAPI 应用对象。`app` 本身就是一个符合 ASGI 规范的可调用对象,可直接交给 uvicorn/hypercorn 等 ASGI 服务器运行(`uvicorn 模块名:app`)。

@app.get("/") # 【装饰器语法】。`@app.get` 是 FastAPI 提供的【路由注册装饰器】,参数 `"/"` 是 URL 路径。等价于把下面的函数注册为:当收到 `GET /` 请求时,调用该函数处理。FastAPI 还提供 `@app.post`、`@app.put`、`@app.delete` 等对应其他 HTTP 方法。
async def root(): # `async def` 声明一个**异步协程函数**作为【路径操作函数】(path operation function)。无参数。
    return {"message": "Hello World"} # 返回1个 Python 字典。FastAPI 会自动将其【序列化为 JSON】,并设置 `Content-Type: application/json` 响应头,状态码默认 200。无需手动构造 `JSONResponse`。

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None): # 异步视图函数,2个参数:
# `item_id: int`:与路径中的 `{item_id}` 同名,FastAPI 自动从 URL 提取并【按类型注解 `int` 做转换和校验】。传非整数(如 `/items/abc`)会自动返回 422 【校验错误】。
# `q: str = None`:参数名不在路径中,且有默认值,因此被识别为【查询参数】(如 `/items/1?q=foo`)。`q = None` 表示可选,不传时为 `None`。
    return {"item_id": item_id, "q": q}

运行方式:保存为 main.py 后执行 uvicorn main:app --reload,访问 http://127.0.0.1:8000/http://127.0.0.1:8000/items/5?q=test 即可验证;自带交互式文档在 /docs

启动:

uvicorn main:app --reload

常用参数

参数 说明 示例
--host 绑定主机 0.0.0.0
--port 绑定端口 8000
--reload 热重载(开发用) -
--workers 工作进程数 4
--log-level 日志级别 info
--ssl-keyfile SSL 密钥 key.pem
--ssl-certfile SSL 证书 cert.pem

生产环境配置

# 生产环境(多进程,无热重载)
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4

# 或使用 gunicorn + uvicorn
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker

程序化运行

import uvicorn

if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
        log_level="info"
    )

性能对比

服务器 性能 特点
Uvicorn ⭐⭐⭐⭐⭐ 最快,纯 ASGI
Gunicorn ⭐⭐⭐⭐ 稳定,WSGI
Daphne ⭐⭐⭐ Django Channels 默认

快速检查清单

Y 推荐文献

X 参考文献

posted @ 2026-04-10 00:52  千千寰宇  阅读(107)  评论(0)    收藏  举报