uvicorn
是一个高性能的 ASGI(Asynchronous Server Gateway Interface)服务器实现,用于运行 Python 异步 Web 应用程序。它基于 asyncio
和 uvloop
(可选),以其速度快、轻量和对异步框架(如 FastAPI、Starlette)的优秀支持而闻名。uvicorn
是 FastAPI 应用的首选服务器,常用于生产环境和开发调试。
以下是对 uvicorn
库的详细介绍,包括其功能、用法和实际应用。
uvloop
(高性能事件循环)和 httptools
,提供低延迟和高并发。asyncio
,适合现代异步框架。asgiref
:ASGI 规范实现。h11
:HTTP/1.1 协议实现。uvloop
(高性能事件循环)、httptools
(HTTP 解析)、websockets
(WebSocket 支持)。pip install uvicorn
uvloop
、httptools
、websockets
):pip install "uvicorn[standard]"
import uvicorn
print(uvicorn.__version__) # 示例输出: 0.32.0
系统依赖(可选):
uvloop
需 C 编译器(如 gcc
):# Ubuntu
sudo apt-get install build-essential python3-dev
# MacOS
xcode-select --install
uvicorn
提供命令行接口(CLI)和编程接口,支持开发和生产环境。以下是主要功能和示例。
通过 CLI 启动 ASGI 应用。
# 运行 FastAPI 应用
uvicorn main:app --host 0.0.0.0 --port 8000
示例(FastAPI 应用):
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello, World!"}
运行:
uvicorn main:app
输出示例:
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
访问:打开 http://127.0.0.1:8000
,返回 {"message": "Hello, World!"}
。
常用 CLI 参数:
--host
:绑定主机(如 0.0.0.0
允许外部访问)。--port
:端口号(默认 8000)。--reload
:开发模式,代码更改后自动重启:uvicorn main:app --reload
--workers
:多进程工作进程数(生产环境):uvicorn main:app --workers 4
--env-file
:加载环境变量文件:uvicorn main:app --env-file .env
--ssl-keyfile
/--ssl-certfile
:启用 HTTPS:uvicorn main:app --ssl-keyfile key.pem --ssl-certfile cert.pem
通过 Python 代码运行 uvicorn
。
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello, World!"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
说明:
uvicorn.run()
:以编程方式启动服务器。reload=True
、workers=4
)。启用 --reload
自动重启。
# main.py
import uvicorn
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
说明:
main.py
后,uvicorn
自动重启应用。使用多工作进程提高并发。
uvicorn main:app --workers 4 --host 0.0.0.0 --port 8000
编程方式:
uvicorn.run(app, host="0.0.0.0", port=8000, workers=4)
说明:
workers
:工作进程数,通常设为 CPU 核心数的 2-4 倍。gunicorn
或确保系统支持 fork
。运行支持 WebSocket 的应用。
from fastapi import FastAPI, WebSocket
from uvicorn import Config, Server
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
await websocket.send_text("Hello, WebSocket!")
await websocket.close()
if __name__ == "__main__":
config = Config(app=app, host="0.0.0.0", port=8000, ws="websockets")
server = Server(config)
server.run()
说明:
ws="websockets"
:启用 WebSocket 支持,需安装 websockets
。自定义日志级别和格式。
uvicorn main:app --log-level debug
编程方式:
import uvicorn
from fastapi import FastAPI
app = FastAPI()
uvicorn.run(
app,
host="0.0.0.0",
port=8000,
log_level="debug",
log_config={
"version": 1,
"formatters": {
"default": {
"format": "%(asctime)s - %(levelname)s - %(message)s"
}
}
}
)
说明:
log_level
:支持 critical
、error
、warning
、info
、debug
。log_config
:自定义日志格式,兼容 Python logging
配置。在生产环境中使用 gunicorn
管理 uvicorn
工作进程。
pip install gunicorn
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
说明:
gunicorn
提供进程管理和负载均衡。UvicornWorker
确保 ASGI 兼容性。uvloop
和 httptools
,性能接近 Node.js 和 Go。asyncio
,支持高并发。--reload
模式不适合生产环境。websockets
库。--reload
快速迭代。gunicorn
或 Nginx 配合,提供高可用服务。示例(FastAPI + WebSocket):
from fastapi import FastAPI, WebSocket
from loguru import logger
import uvicorn
app = FastAPI()
@app.get("/health")
async def health():
logger.info("Health check requested")
return {"status": "ok"}
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
logger.info(f"Received: {data}")
await websocket.send_text(f"Echo: {data}")
except Exception as e:
logger.error(f"WebSocket error: {e}")
finally:
await websocket.close()
if __name__ == "__main__":
logger.add("app.log", rotation="1 MB", level="INFO")
uvicorn.run(
app,
host="0.0.0.0",
port=8000,
log_level="info",
ws="websockets",
reload=True
)
运行:
uvicorn main:app --reload
说明:
/health
REST 端点和 /ws
WebSocket 端点。loguru
记录请求和错误。--reload
支持开发模式。uvicorn main:app --reload --host 127.0.0.1 --port 8000
uvicorn main:app --workers 4 --host 0.0.0.0 --port 8000
gunicorn
:gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
uvicorn main:app --ssl-keyfile key.pem --ssl-certfile cert.pem
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
uvloop
和 httptools
:pip install uvloop httptools
workers
数:2 * CPU 核心数 + 1
。limit-concurrency
限制最大连接数:uvicorn main:app --limit-concurrency 1000
--reload
和 log_level="debug"
。gunicorn
或 supervisord 管理进程。websockets
:pip install websockets
stderr
)。loguru
或 logging
自定义日志。uvicorn
0.32.0 支持 Python 3.8+,与 FastAPI 0.115+ 兼容。asgiref>=3.4
)。以下是一个综合示例,结合 uvicorn
、FastAPI
、loguru
和 httpx
,展示 REST 和 WebSocket 功能:
from fastapi import FastAPI, WebSocket, Depends
from loguru import logger
import uvicorn
import httpx
from typing_extensions import Literal
from pydantic import BaseModel
# 配置日志
logger.add("app.log", rotation="1 MB", level="INFO")
app = FastAPI()
class HealthResponse(BaseModel):
status: Literal["ok", "error"]
async def get_client():
return httpx.AsyncClient()
@app.get("/health", response_model=HealthResponse)
async def health():
logger.info("Health check")
return {"status": "ok"}
@app.get("/fetch")
async def fetch_external(client: httpx.AsyncClient = Depends(get_client)):
try:
response = await client.get("https://api.github.com/repos/encode/uvicorn")
logger.info("Fetched external data")
return response.json()
except httpx.HTTPStatusError as e:
logger.error(f"HTTP error: {e}")
raise HTTPException(status_code=500, detail=str(e))
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
logger.info(f"WebSocket received: {data}")
await websocket.send_text(f"Echo: {data}")
except Exception as e:
logger.error(f"WebSocket error: {e}")
await websocket.close()
if __name__ == "__main__":
uvicorn.run(
app,
host="0.0.0.0",
port=8000,
log_level="info",
ws="websockets",
reload=True,
env_file=".env"
)
运行:
uvicorn main:app --reload
功能:
/health
:返回健康状态。/fetch
:调用外部 API(GitHub)。/ws
:WebSocket 回显服务。loguru
记录日志,typing_extensions
增强类型注解。日志示例(app.log):
2025-05-09T12:34:56.123 | INFO | Health check
2025-05-09T12:34:56.124 | INFO | Fetched external data
2025-05-09T12:34:56.125 | INFO | WebSocket received: hello
uvicorn
标签):https://stackoverflow.com/questions/tagged/uvicorn