导航菜单

  • 1.vector
  • 2.milvus
  • 3.pymilvus
  • 4.rag
  • 5.rag_measure
  • ragflow
  • heapq
  • HNSW
  • cosine_similarity
  • math
  • typing
  • etcd
  • minio
  • collections
  • jieba
  • random
  • beautifulsoup4
  • chromadb
  • sentence_transformers
  • numpy
  • lxml
  • openpyxl
  • PyMuPDF
  • python-docx
  • requests
  • python-pptx
  • text_splitter
  • all-MiniLM-L6-v2
  • openai
  • llm
  • BPETokenizer
  • Flask
  • RAGAS
  • BagofWords
  • langchain
  • Pydantic
  • abc
  • faiss
  • MMR
  • scikit-learn
  • Runnable
  • PromptEngineering
  • dataclasses
  • LaTeX
  • rank_bm25
  • TF-IDF
  • asyncio
  • sqlalchemy
  • fastapi
  • Starlette
  • uvicorn
  • argparse
  • Generic
  • ssl
  • urllib
  • python-dotenv
  • RRF
  • CrossEncoder
  • Lost-in-the-middle
  • Jinja2
  • logger
  • io
  • venv
  • concurrent
  • parameter
  • SSE
  • 1. Uvicorn 是什么?它解决什么问题?
    • 1.1 为什么需要 Uvicorn?
    • 1.2 Uvicorn 的核心特点
  • 2. 前置知识
    • 2.1 什么是服务器?
    • 2.2 什么是 ASGI?
    • 2.3 异步编程基础
    • 2.4 Python 基础知识
  • 3. 安装与环境准备
    • 3.1 安装 Uvicorn
    • 3.2 验证安装
  • 4. 基本使用:命令行方式
    • 4.1 创建示例应用
    • 4.2 运行应用
  • 5. 基本使用:Python 代码方式
    • 5.1 使用 uvicorn.run() 函数
    • 5.2 使用字符串指定应用
  • 6. 常用配置选项
    • 6.1 基本配置
    • 6.2 开发环境配置
    • 6.3 生产环境配置(简化版)
  • 7. 运行 FastAPI 应用
    • 7.1 创建 FastAPI 应用
    • 7.2 使用命令行运行
  • 8. 运行 Starlette 应用
    • 8.1 创建 Starlette 应用
    • 8.2 使用命令行运行
  • 9. 热重载:开发时的便利功能
    • 9.1 启用热重载
  • 10. 日志配置:查看服务器运行信息
    • 10.1 日志级别
    • 10.2 查看日志输出
  • 11. 多进程模式:提高并发能力
    • 11.1 单进程模式(开发环境)
    • 11.2 多进程模式(生产环境)
  • 12. 常见错误与最佳实践
    • 12.1 常见错误
      • 错误 1:找不到应用
      • 错误 2:端口已被占用
      • 错误 3:忘记启用热重载
    • 12.2 最佳实践
  • 13. Uvicorn 与其他组件的关系
    • 13.1 Uvicorn 在 Web 开发中的位置
    • 13.2 为什么选择 Uvicorn?
  • 14. 总结
    • 14.1 核心概念回顾
    • 14.2 基本使用流程

1. Uvicorn 是什么?它解决什么问题? #

Uvicorn 是一个轻量级、超快速的 ASGI(异步服务器网关接口)服务器。它是运行 FastAPI、Starlette 等异步 Web 应用的服务器程序。

1.1 为什么需要 Uvicorn? #

简单理解:

  • FastAPI/Starlette:Web 框架,定义了如何处理请求和返回响应
  • Uvicorn:服务器,负责接收 HTTP 请求、调用框架、返回响应

类比:

  • 框架 = 餐厅的菜单和厨师(定义做什么菜)
  • 服务器 = 餐厅的服务员(负责接待客人、传递订单)

1.2 Uvicorn 的核心特点 #

  1. 极高性能:基于 uvloop(高性能事件循环)和 httptools(C 语言 HTTP 解析器)
  2. ASGI 兼容:完全支持异步 Web 应用
  3. 轻量级:代码简洁,依赖少
  4. 易于使用:简单的命令行接口和 Python API

2. 前置知识 #

在学习 Uvicorn 之前,你需要了解以下基础知识。

2.1 什么是服务器? #

服务器(Server) 是运行在计算机上的程序,它:

  • 监听网络端口(如 8000)
  • 接收客户端(如浏览器)的请求
  • 处理请求并返回响应

简单理解:服务器就像一个餐厅,等待客人(客户端)来点餐(发送请求),然后提供食物(返回响应)。

2.2 什么是 ASGI? #

ASGI(Asynchronous Server Gateway Interface,异步服务器网关接口) 是 Python Web 应用和服务器之间的标准接口。

ASGI vs WSGI:

  • WSGI(旧标准):同步接口,一次只能处理一个请求
  • ASGI(新标准):异步接口,可以同时处理多个请求

为什么需要 ASGI:

  • 支持异步编程(async/await)
  • 支持 WebSocket
  • 性能更好

2.3 异步编程基础 #

Uvicorn 是异步服务器,你需要了解:

  • async def:定义异步函数
  • await:等待异步操作完成
  • asyncio:Python 的异步编程库

如果你不熟悉异步编程,建议先学习 Python 的 asyncio 模块。

2.4 Python 基础知识 #

你需要熟悉:

  • 模块导入:import 语句
  • 函数调用:如何调用函数
  • 命令行:基本的命令行操作

3. 安装与环境准备 #

3.1 安装 Uvicorn #

使用 pip 安装:

# 标准版(推荐)
pip install uvicorn[standard]

# 或者基础版
pip install uvicorn

说明:

  • uvicorn[standard]:包含所有推荐依赖(uvloop、httptools 等),性能更好
  • uvicorn:基础版本,功能完整但性能稍差

3.2 验证安装 #

创建一个简单的测试应用 test_app.py:

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

# 定义处理函数
async def homepage(request):
    # 返回 JSON 响应
    return JSONResponse({"message": "Uvicorn 安装成功!"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", homepage),
    ]
)

# 运行应用(使用 uvicorn)
if __name__ == "__main__":
    import uvicorn
    # 运行服务器,监听 8000 端口
    uvicorn.run(app, host="0.0.0.0", port=8000)

运行测试:

python test_app.py

然后在浏览器访问 http://localhost:8000,应该能看到 {"message": "Uvicorn 安装成功!"}。

4. 基本使用:命令行方式 #

Uvicorn 最简单的使用方式是通过命令行运行。

4.1 创建示例应用 #

首先,创建一个简单的应用 main.py:

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

# 定义处理函数
async def read_root(request):
    # 返回 JSON 响应
    return JSONResponse({"message": "Hello Uvicorn!"})

# 创建应用实例
# 变量名必须是 app(命令行默认查找这个变量)
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

4.2 运行应用 #

在命令行中运行:

# 基本运行(默认监听 127.0.0.1:8000)
uvicorn main:app

# 指定主机和端口
uvicorn main:app --host 0.0.0.0 --port 8000

# 启用热重载(开发模式,代码修改后自动重启)
uvicorn main:app --reload

# 设置日志级别
uvicorn main:app --log-level debug

命令说明:

  • main:app:main 是文件名(不含 .py),app 是应用实例的变量名
  • --host 0.0.0.0:监听所有网络接口(允许外部访问)
  • --port 8000:使用 8000 端口
  • --reload:开发模式,代码修改后自动重启服务器
  • --log-level debug:设置日志级别为 debug(显示详细信息)

5. 基本使用:Python 代码方式 #

除了命令行,你也可以在 Python 代码中直接运行 Uvicorn。

5.1 使用 uvicorn.run() 函数 #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    # 返回 JSON 响应
    return JSONResponse({"message": "Hello from Python!"})

# 创建应用实例
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 在 Python 代码中运行服务器
# uvicorn.run() 函数用于启动服务器
if __name__ == "__main__":
    # 方式 1:传入应用实例
    uvicorn.run(
        app,              # 应用实例
        host="0.0.0.0",  # 主机地址
        port=8000,       # 端口号
        reload=True      # 是否启用热重载(开发模式)
    )

5.2 使用字符串指定应用 #

# 导入必要的模块
import uvicorn

# 使用字符串指定应用位置
# "main:app" 表示 main.py 文件中的 app 变量
if __name__ == "__main__":
    uvicorn.run(
        "main:app",      # 应用位置(字符串格式)
        host="0.0.0.0",  # 主机地址
        port=8000,       # 端口号
        reload=True,     # 启用热重载
        log_level="info" # 日志级别
    )

两种方式的区别:

  • 传入应用实例:直接传入应用对象,更直观
  • 传入字符串:Uvicorn 会自动导入,适合应用在其他文件中定义

6. 常用配置选项 #

Uvicorn 提供了丰富的配置选项,让我们学习最常用的几个。

6.1 基本配置 #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    return JSONResponse({"message": "Hello Uvicorn!"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 运行应用,配置常用选项
if __name__ == "__main__":
    uvicorn.run(
        app,
        host="0.0.0.0",      # 主机地址(0.0.0.0 表示监听所有网络接口)
        port=8000,           # 端口号
        reload=True,         # 是否启用热重载(开发时使用)
        log_level="info",    # 日志级别:critical, error, warning, info, debug, trace
        access_log=True,     # 是否记录访问日志
        workers=1            # 工作进程数(开发时通常为 1,生产环境可以增加)
    )

6.2 开发环境配置 #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    return JSONResponse({"message": "开发模式"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 开发环境配置
if __name__ == "__main__":
    uvicorn.run(
        app,
        host="127.0.0.1",    # 只监听本地(更安全)
        port=8000,
        reload=True,         # 启用热重载
        reload_dirs=["./"],  # 监听哪些目录的变化
        log_level="debug",   # 详细的日志(便于调试)
        access_log=True      # 记录访问日志
    )

6.3 生产环境配置(简化版) #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    return JSONResponse({"message": "生产模式"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 生产环境配置(简化版)
if __name__ == "__main__":
    uvicorn.run(
        app,
        host="0.0.0.0",      # 监听所有网络接口
        port=8000,
        reload=False,        # 禁用热重载(生产环境不需要)
        log_level="warning", # 只记录警告和错误
        access_log=True,     # 记录访问日志
        workers=4            # 使用多个工作进程(根据 CPU 核心数调整)
    )

配置说明:

  • host:服务器监听的主机地址
    • 127.0.0.1:只允许本地访问
    • 0.0.0.0:允许所有网络接口访问
  • port:服务器监听的端口号
  • reload:是否启用热重载(开发时使用,生产环境禁用)
  • log_level:日志级别,从低到高:critical < error < warning < info < debug < trace
  • access_log:是否记录访问日志
  • workers:工作进程数(多进程模式,提高并发能力)

7. 运行 FastAPI 应用 #

Uvicorn 最常用的场景是运行 FastAPI 应用。

7.1 创建 FastAPI 应用 #

# 导入 FastAPI
from fastapi import FastAPI

# 创建 FastAPI 应用实例
app = FastAPI()

# 定义路由
@app.get("/")
async def read_root():
    # 返回 JSON 响应
    return {"message": "Hello FastAPI with Uvicorn!"}

# 运行应用
if __name__ == "__main__":
    import uvicorn
    # 运行 FastAPI 应用
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)

7.2 使用命令行运行 #

# 运行 FastAPI 应用
uvicorn main:app --reload

# 访问 http://localhost:8000 查看应用
# 访问 http://localhost:8000/docs 查看自动生成的 API 文档

8. 运行 Starlette 应用 #

Uvicorn 也可以运行 Starlette 应用。

8.1 创建 Starlette 应用 #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

# 定义处理函数
async def read_root(request):
    # 返回 JSON 响应
    return JSONResponse({"message": "Hello Starlette with Uvicorn!"})

# 创建 Starlette 应用实例
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 运行应用
if __name__ == "__main__":
    import uvicorn
    # 运行 Starlette 应用
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)

8.2 使用命令行运行 #

# 运行 Starlette 应用
uvicorn main:app --reload

# 访问 http://localhost:8000 查看应用

9. 热重载:开发时的便利功能 #

热重载(Hot Reload) 是开发时的便利功能:当你修改代码后,服务器会自动重启,无需手动停止和启动。

9.1 启用热重载 #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    # 修改这里的返回值,保存文件后服务器会自动重启
    return JSONResponse({"message": "修改我,然后保存文件!"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 启用热重载
if __name__ == "__main__":
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        reload=True,         # 启用热重载
        reload_dirs=["./"]  # 监听当前目录的变化
    )

使用方法:

  1. 运行程序
  2. 修改代码(如修改返回的消息)
  3. 保存文件
  4. 服务器会自动检测变化并重启
  5. 刷新浏览器即可看到新内容

注意:热重载只在开发时使用,生产环境应该禁用(reload=False)。

10. 日志配置:查看服务器运行信息 #

Uvicorn 提供了详细的日志功能,帮助你了解服务器的运行状态。

10.1 日志级别 #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    return JSONResponse({"message": "查看日志输出"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 配置不同的日志级别
if __name__ == "__main__":
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        log_level="debug",  # 日志级别:critical, error, warning, info, debug, trace
        access_log=True      # 是否记录访问日志
    )

日志级别说明:

  • critical:只显示严重错误
  • error:显示错误信息
  • warning:显示警告信息
  • info:显示一般信息(默认)
  • debug:显示调试信息(最详细)
  • trace:显示跟踪信息(最最详细)

10.2 查看日志输出 #

运行服务器后,你会看到类似以下的日志输出:

INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:54321 - "GET / HTTP/1.1" 200 OK

日志说明:

  • 第一行:服务器进程已启动
  • 第二行:等待应用启动
  • 第三行:应用启动完成
  • 第四行:服务器运行地址
  • 第五行:访问日志(客户端 IP、请求方法、路径、状态码)

11. 多进程模式:提高并发能力 #

默认情况下,Uvicorn 使用单进程模式。对于生产环境,可以使用多进程模式提高并发能力。

11.1 单进程模式(开发环境) #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn

# 定义处理函数
async def read_root(request):
    return JSONResponse({"message": "单进程模式"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 单进程模式(默认)
if __name__ == "__main__":
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        workers=1  # 单进程(开发环境)
    )

11.2 多进程模式(生产环境) #

# 导入必要的模块
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn
import multiprocessing

# 定义处理函数
async def read_root(request):
    return JSONResponse({"message": "多进程模式"})

# 创建应用
app = Starlette(
    routes=[
        Route("/", read_root),
    ]
)

# 多进程模式
if __name__ == "__main__":
    # 获取 CPU 核心数
    cpu_count = multiprocessing.cpu_count()
    # 工作进程数通常是 CPU 核心数的 2 倍 + 1
    workers = cpu_count * 2 + 1

    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        workers=workers,     # 多进程(生产环境)
        reload=False         # 生产环境禁用热重载
    )

说明:

  • 单进程模式:适合开发环境,简单易用
  • 多进程模式:适合生产环境,提高并发处理能力
  • workers 数量:通常设置为 CPU 核心数的 2 倍 + 1

12. 常见错误与最佳实践 #

12.1 常见错误 #

错误 1:找不到应用 #

# 错误:应用变量名不匹配
# main.py 中定义的是 my_app,但命令行使用的是 app
uvicorn main:app  # 错误:找不到 app 变量

# 正确:使用正确的变量名
uvicorn main:my_app  # 正确

错误 2:端口已被占用 #

# 错误:端口 8000 已被其他程序占用
uvicorn.run(app, port=8000)  # 可能报错:Address already in use

# 正确:使用其他端口
uvicorn.run(app, port=8001)  # 使用 8001 端口

错误 3:忘记启用热重载 #

# 开发时忘记启用热重载,每次修改代码都要手动重启
uvicorn.run(app, reload=False)  # 不方便

# 正确:开发时启用热重载
uvicorn.run(app, reload=True)  # 方便

12.2 最佳实践 #

  1. 开发环境:

    • 使用 reload=True 启用热重载
    • 使用 log_level="debug" 查看详细信息
    • 使用 workers=1 单进程模式
  2. 生产环境:

    • 使用 reload=False 禁用热重载
    • 使用 log_level="warning" 只记录警告和错误
    • 使用 workers=4 或更多(根据 CPU 核心数)
  3. 端口选择:

    • 开发环境:使用 8000、8001 等常用端口
    • 生产环境:使用标准端口(80、443)或配置反向代理

13. Uvicorn 与其他组件的关系 #

13.1 Uvicorn 在 Web 开发中的位置 #

客户端(浏览器)
    ↓
Uvicorn(服务器)
    ↓
FastAPI/Starlette(框架)
    ↓
你的应用代码

简单理解:

  • 客户端:发送请求(如浏览器)
  • Uvicorn:接收请求,调用框架
  • 框架:处理请求,执行你的代码
  • 你的代码:处理业务逻辑,返回响应

13.2 为什么选择 Uvicorn? #

  1. 性能优秀:基于 uvloop 和 httptools,性能极佳
  2. 简单易用:配置简单,API 清晰
  3. 生态良好:与 FastAPI、Starlette 完美集成
  4. 功能完整:支持异步、WebSocket 等特性

14. 总结 #

14.1 核心概念回顾 #

  • Uvicorn:ASGI 服务器,用于运行异步 Web 应用
  • ASGI:异步服务器网关接口
  • 热重载:开发时自动重启服务器
  • 多进程模式:提高并发处理能力
  • 日志级别:控制日志输出的详细程度

14.2 基本使用流程 #

  1. 安装 Uvicorn:pip install uvicorn[standard]
  2. 创建应用(FastAPI 或 Starlette)
  3. 运行应用:
    • 命令行:uvicorn main:app --reload
    • Python 代码:uvicorn.run(app, host="0.0.0.0", port=8000)
← 上一节 urllib 下一节 venv →

访问验证

请输入访问令牌

Token不正确,请重新输入