术→技巧, 研发, 运维

FastAPI应用线上部署方案

钱魏Way · · 302 次浏览
!文章内容如有错误或排版问题,请提交反馈,非常感谢!

在先前的文章Python Web 应用的线上部署 中,主要讲解了如何部署 Flask 和 Django,虽然涉及了部分 ASGI 服务器的相关部署知识,但是介绍的非常的简单,今天就针对 FastAPI 应用如何部署到线上服务器进行比较详细的介绍。

Gunicorn 与 uWSGI 的异步支持

Gunicorn 的异步支持

Gunicorn 是一个基于 WSGI 的 HTTP 服务器,默认用于同步应用,但通过使用异步 Worker 类型

Gevent/Eventlet

通过协程库实现异步 I/O,适用于需要高并发的同步应用(如 Flask/Django)。

# 使用 Gevent Worker
gunicorn app:app -k gevent

# 使用 Eventlet Worker
gunicorn app:app -k eventlet

适用场景:同步代码改造为异步,但需注意协程兼容性。

Uvicorn Worker

直接运行 ASGI 应用(如 FastAPI/Starlette),通过 uvicorn.workers.UvicornWorker 支持异步。

gunicorn app:app -k uvicorn.workers.UvicornWorker

优势:原生支持 ASGI 协议,适合纯异步应用。

性能与限制

  • 适用性
    • gevent/eventlet 适合改造现有同步项目。
    • uvicorn Worker 是部署 FastAPI 的推荐方案。
  • 限制
    • 协程模式下需避免阻塞操作(如同步数据库驱动)。
    • 原生异步应用需直接使用 ASGI Worker(如 Uvicorn)。

uWSGI 的异步支持

uWSGI 是一个多协议服务器,支持同步(WSGI)和异步(ASGI)应用,但配置复杂。

Gevent 插件

通过 –gevent 或 –async 参数启用协程异步。

uwsgi --http :8000 --gevent 100 --wsgi-file app.py

原生 ASGI 支持

需安装 uwsgi 的 ASGI 插件(如 asyncio),但支持有限。

uwsgi --http :8000 --asgi-file app:app --async 100

性能与限制

  • 优势
    • 支持多种协议(WSGI/ASGI/HTTP)。
    • 可通过 –processes 和 –threads 灵活配置多进程+多线程。
  • 缺点
    • ASGI 支持不如 Uvicorn 成熟,社区资源较少。
    • 配置复杂,文档分散,调试困难。

对比总结

特性 Gunicorn uWSGI
默认协议 WSGI(同步) WSGI/ASGI(需配置)
异步支持方式 通过协程 Worker 或 Uvicorn ASGI Worker 通过 Gevent 插件或原生 ASGI 模式
部署 FastAPI 推荐 ✅ 首选(Gunicorn+Uvicorn Worker) ❌ 不推荐(配置复杂,性能不优)
适用场景 异步应用、轻量级部署 复杂多协议需求、传统同步项目改造
配置复杂度 简单 复杂
社区生态 活跃(广泛用于 Python 生态) 成熟但分散(多语言支持导致文档杂乱)

部署示例

Gunicorn+Uvicorn(推荐)

# 安装依赖
pip install gunicorn uvicorn[standard]

# 启动 FastAPI 应用
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker

uWSGI+ASGI(不推荐)

# 安装 uWSGI 和 ASGI 插件
pip install uwsgi

# 启动 ASGI 应用(需确认插件支持)
uwsgi --http :8000 --asgi-file main:app --async 100

注意事项

  • Gunicorn 的 Uvicorn Worker
    • 是部署 FastAPI 的标准方案,性能优于 uWSGI。
    • 需通过 -w 指定工作进程数(通常为 CPU 核心数×2)。
  • uWSGI 的异步模式
    • 主要用于遗留系统改造,新项目建议优先选择 Gunicorn+Uvicorn。
    • WebSocket 支持需额外配置,不如 ASGI 服务器原生支持稳定。
  • 性能调优
    • 异步模式下需监控 CPU/内存,避免协程泄露或阻塞操作。
    • 静态文件处理建议交给反向代理(如 Nginx)以提高效率。

通过合理选择工具,Gunicorn 和 uWSGI 均可支持异步应用,但Gunicorn+Uvicorn 组合在易用性和性能上更胜一筹,是 Python 异步生态的现代部署方案。

FastAPI 的基础部署(测试环境)

安装依赖

# 安装 FastAPI 和 ASGI 服务器(如 Uvicorn)
pip install fastapi uvicorn[standard]

# 可选:安装其他依赖(如数据库驱动)
pip install sqlalchemy databases[postgresql]

启动开发服务器(仅调试)

uvicorn main:app --reload
  • main:app:py 文件中的 app 实例。
  • –reload:代码变更时自动重启(仅用于开发环境)。

FastAPI 生产环境部署方案

使用 ASGI 服务器(Uvicorn/Hypercorn)

FastAPI 基于 ASGI 规范,生产环境需搭配高性能 ASGI 服务器。

单进程启动(简单场景)

uvicorn main:app --host 0.0.0.0 --port 80

多进程启动(推荐)

使用 Gunicorn 作为进程管理器,配合 Uvicorn 工作进程:

pip install gunicorn

启动命令:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
  • -w 4:启动 4 个工作进程(根据 CPU 核心数调整)。
  • -k uvicorn.workers.UvicornWorker:指定 Uvicorn 作为工作进程。

配置反向代理(Nginx/Caddy)

通过反向代理处理 HTTPS、静态文件和负载均衡。

Nginx 配置示例

server {
    listen 80;
    server_name your_domain.com;

    # 重定向 HTTP 到 HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name your_domain.com;

    # SSL 证书配置
    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;

    # 静态文件处理(可选)
    location /static {
        alias /path/to/static/files;
    }

    # 反向代理到 FastAPI
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Caddy 配置示例(更简洁)

your_domain.com {
    encode gzip
    reverse_proxy localhost:8000
    tls /etc/ssl/certs/fullchain.pem /etc/ssl/private/privkey.pem
}

进程管理(Systemd/Docker)

确保应用在服务器重启后自动运行。

Systemd 服务配置

创建文件 /etc/systemd/system/fastapi.service:

[Unit]
Description=FastAPI Application
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/path/to/app
ExecStart=/usr/local/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
Restart=always

[Install]
WantedBy=multi-user.target

启用服务:

sudo systemctl daemon-reload
sudo systemctl start fastapi
sudo systemctl enable fastapi

Docker 部署

创建 Dockerfile:

FROM python:3.9-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "main:app"]

构建并运行:

docker build -t fastapi-app .
docker run -d -p 8000:8000 fastapi-app

HTTPS 配置(Let’s Encrypt)

使用 Certbot 自动获取免费 SSL 证书:

# 安装 Certbot
sudo apt install certbot python3-certbot-nginx

# 获取证书(Nginx)
sudo certbot --nginx -d your_domain.com

FastAPI 高级部署方案

容器化集群(Docker Compose/Kubernetes)

Docker Compose 示例

version: '3'
services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:password@db/app
  db:
    image: postgres:13
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=app

Kubernetes 部署

定义 Deployment 和 Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
      - name: app
        image: your-registry/fastapi-app:latest
        ports:
        - containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: fastapi-service
spec:
  selector:
    app: fastapi
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
  type: LoadBalancer

Serverless 部署(AWS Lambda/Google Cloud Run)

AWS Lambda + API Gateway

使用 Mangum 适配 FastAPI 到 Lambda:

pip install mangum

修改 main.py:

from fastapi import FastAPI
from mangum import Mangum

app = FastAPI()
handler = Mangum(app)

部署工具推荐

工具 用途 示例场景
Uvicorn/Gunicorn ASGI 服务器 单机多进程部署
Nginx/Caddy 反向代理 & HTTPS 生产环境流量分发
Docker 容器化部署 跨环境一致性部署
Kubernetes 容器编排 & 集群管理 微服务架构扩展
Systemd Linux 进程管理 服务器后台运行

注意事项

  • 禁用调试模式:生产环境移除 –reload 和 debug=True。
  • 环境变量管理:使用 .env 文件或工具(如 python-dotenv)管理敏感配置。
  • 监控与日志:集成 Prometheus、Grafana 或 Sentry 监控应用状态。
  • 零停机部署:使用 Gunicorn 的 –preload 或 Kubernetes 滚动更新。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注