




























python fast api 部署
1.新建gunicron_config.py
# 基本配置 workers = multiprocessing.cpu_count() worker_class = "uvicorn.workers.UvicornWorker" # worker_class = "ads_agent_svr.uvicorn_worker.GracefulUvicornWorker" bind = "0.0.0.0:29796" timeout = 30 # 工作进程无请求超时时间 graceful_timeout = 15 # 优雅退出超时时间 keepalive = 5 # 保持连接时间
带日志的gunicron_config.py
import multiprocessing import os from pathlib import Path from config import config as app_config # ========================= # 日志路径准备 # ========================= server_log_path = app_config.get("SERVER_LOG_PATH", "./logs/server.log") log_file = Path(server_log_path) log_file.parent.mkdir(parents=True, exist_ok=True) # ========================= # 基本配置 # ========================= workers = multiprocessing.cpu_count() worker_class = "uvicorn.workers.UvicornWorker" bind = "0.0.0.0:29796" timeout = 30 graceful_timeout = 15 keepalive = 5 accesslog = "-" # access log 输出到 stdout errorlog = "-" # error log 输出到 stdout loglevel = "INFO" # ========================= # logging 配置 # ========================= logconfig_dict = { "version": 1, "disable_existing_loggers": False, # ---------- format ---------- "formatters": { "standard": { "format": "%(asctime)s [%(levelname)s] [pid:%(process)d] [%(name)s] %(message)s", }, "access": { "format": "%(asctime)s [ACCESS] [pid:%(process)d] %(message)s", }, }, # ---------- handlers ---------- "handlers": { # 控制台 "console": { "class": "logging.StreamHandler", "formatter": "standard", "level": "INFO", }, # access console "access_console": { "class": "logging.StreamHandler", "formatter": "access", "level": "INFO", }, # 文件日志 "file": { "class": "logging.handlers.RotatingFileHandler", "formatter": "standard", "filename": server_log_path, "maxBytes": 50 * 1024 * 1024, # 50MB "backupCount": 5, "encoding": "utf8", }, }, # ---------- loggers ---------- "loggers": { # gunicorn 错误日志 "gunicorn.error": { "handlers": ["console", "file"], "level": "INFO", "propagate": True, }, # gunicorn access 日志 "gunicorn.access": { "handlers": ["access_console", "file"], "level": "INFO", "propagate": False, }, # uvicorn error "uvicorn.error": { "handlers": ["console", "file"], "level": "INFO", "propagate": True, }, # uvicorn access "uvicorn.access": { "handlers": ["access_console", "file"], "level": "INFO", "propagate": False, }, # 业务 logger "news2video": { "handlers": ["console", "file"], "level": "INFO", "propagate": False, }, }, # ---------- root logger ---------- "root": { "handlers": ["console", "file"], "level": "INFO", }, }
2.run_with_gunicron.sh
gunicorn -c scripts/conf/gunicorn_config.py ads_agent_svr.app:app
3.新建system /etc/systemd/system/ads_agent_svr.service
[Unit]
Description=FastAPI Application (Gunicorn + UvicornWorker)
After=network.target
[Service]
User=dev
Group=dev
WorkingDirectory=/app/app_ads_svr/app_ads_svr
Environment="PATH=/app/app_ads_svr/venv/bin"
ExecStart=/app/app_ads_svr/venv/bin/gunicorn \
-c scripts/conf/gunicorn_config.py \
app_ads_svr.app:app \
--worker-class uvicorn.workers.UvicornWorker
Restart=always
[Install]
WantedBy=multi-user.target
重启服务
sudo systemctl restart ads_agent_svr
查看状态
sudo systemctl status ads_agent_svr
重载配置
sudo systemctl daemon-reload
4.nginx 配置
server { listen 80; listen 443 ssl; server_name api-ads-g-test.xxxx.com; #ssl on; client_max_body_size 512m; ssl_certificate /app/certs/xxxx.com/current/server.crt; ssl_certificate_key /app/certs/xxxx.com/current/server.key; access_log /data/ads_agent_svr/logs/nginx/api-ads-g-test.xxxx.com_access.log; error_log /data/ads_agent_svr/logs/nginx/api-ads-g-test.xxxx.com_error.log; location /static/html { alias /data/ads_agent_svr/static/html; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; } location /static/photo/public { alias /data/pickwant/pickwant/generated/static/public; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; } location / { if ($request_method = OPTIONS) { return 204; } # 所有响应都带上 CORS add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always; add_header Access-Control-Allow-Headers 'Authorization,Content-Type,Origin,Accept' always; proxy_pass http://127.0.0.1:29796; 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; # WebSocket 必须的头 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 防止 WebSocket/长轮询被断开 proxy_read_timeout 86400; proxy_send_timeout 86400; } }
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。