FastAPI + NGINX + Gunicorn:部署一个高性能的Python应用

一、前言

FastAPI 是用于开发API应用最受欢迎的Python库之一,NGINX、Gunicorn 和 Uvicorn 都是经过实践验证的技术,常被用作反向代理和ASGI服务器来部署Python网页应用。

file

本文将展示如何结合这些工具来部署一个 FastAPI 网页应用:

介绍FastAPI、NGINX、Gunicorn和Uvicorn的基础知识。
配置Gunicorn + Uvicorn作为ASGI服务器。
设置NGINX作为反向代理服务器。
使用Let's Encrypt生成免费SSL证书。

二、技术框架介绍

FastAPI 是一个现代的、高性能的 Web 框架,借助 Starlette 和 pydantic,FastAPI 提供了与 NodeJS 和 Go 类似的出色性能。FastAPI比Flask快得多,它实际上是Python最快的Web框架之一。

Gunicorn是用于Python应用程序的WSGI服务器的一种实现。Gunicorn是一个符合WSGI标准的Web服务器,用于Python应用程序,它接收从客户端发送到Web服务器的请求,并将其转发到Python应用程序或Web框架(如Flask或Django)上,以便为请求运行适当的应用程序代码。

file

FastAPI 不包含任何内置的开发服务器。因此,我们需要 Uvicorn。它实施ASGI标准,速度快如闪电。ASGI 代表 异步服务器网关接口。Uvicorn 是Python的ASGI Web服务器实现。

Nginx 是一个异步框架的 Web 服务器,也可以用作反向代理,负载平衡器 和 HTTP 缓存。

三、服务器安全设置

  1. 首先,确保服务器拥有最新的软件:
sudo apt update && sudo apt upgrade -y

设置自动安全更新,需要安装并启用 unnattended-upgrades:

sudo apt install unattended-upgrades

安装完成后,编辑文件 /etc/apt/apt.conf.d/20auto-upgrades 并按照以下配置进行设置:

APT::Periodic::Update-Package-Lists "1";  # 每天自动更新软件包列表
APT::Periodic::Unattended-Upgrade "1";    # 系统将自动升级到最新版本的软件包
APT::Periodic::AutocleanInterval "7";     # 每周运行一次自动清理操作,删除旧的和不必要的包文件

最后,在文件 /etc/apt/apt.conf.d/50unattended-upgrades 中进行编辑,以确保系统在需要内核更新时自动重新启动:

Unattended-Upgrade::Automatic-Reboot "true";

完成以上步骤后,系统将自动执行安全更新,并在需要时重新启动以应用内核更新。

  1. 防火墙服务
    如果用的云提供商不提供防火墙服务,可以手动配置防火墙来限制传入流量只能到达必要的端口,例如80、443和22端口。

另外,还可以安装并配置fail2ban来预防暴力身份验证攻击。Fail2ban是一个用于保护Linux服务器免受恶意登录尝试的工具。它监视系统日志文件,并根据设定的规则自动禁止源IP地址。

  1. 安装Supervisor和NGINX:
sudo apt install supervisor nginx -y

Supervisor 是一个用于类Unix操作系统(包括Linux)的进程控制系统,它用于监视和管理程序的进程。NGINX是一种常用的多功能软件,通常用作反向代理来部署Web应用程序。

启用并启动Supervisor:

sudo systemctl enable supervisor
sudo systemctl start supervisor

使用enable命令将确保 Supervisor 在启动时自动启动,并使用start命令立即启动 Supervisor 服务。

四、配置Gunicorn作为WSGI服务器。

  1. 运行FastAPI 应用程序: main.py

    uvicorn main:app
  2. 配置Gunicorn

首先,明确指定 Gunicorn 的配置要求。其次,设置Supervisor 程序来运行Gunicorn。

首先,在项目目录中创建一个名为 gunicorn_start 的文件:

vim gunicorn_start

将以下内容添加到文件中:

#!/bin/bash

NAME=fastapi-app
DIR=/home/fastapi-user/fastapi-nginx-gunicorn
USER=fastapi-user
GROUP=fastapi-user
WORKERS=3
WORKER_CLASS=uvicorn.workers.UvicornWorker
VENV=$DIR/.venv/bin/activate
BIND=unix:$DIR/run/gunicorn.sock
LOG_LEVEL=error

cd $DIR
source $VENV

exec gunicorn main:app \
  --name $NAME \
  --workers $WORKERS \
  --worker-class $WORKER_CLASS \
  --user=$USER \
  --group=$GROUP \
  --bind=$BIND \
  --log-level=$LOG_LEVEL \
  --log-file=-

解释:

第1行表示此脚本将由bash shell执行。

第3行至第11行指定您将传递给Gunicorn的配置选项。大多数参数都是直观的,除了 WORKERS、WORKER_CLASS 和 BIND :

- WORKERS:定义要使用的工作进程数量,通常建议使用CPU核心数+1。
- WORKER_CLASS:指定要使用的工作进程类型。在此示例中,您指定Uvicorn Worker作为ASGI服务器。
- BIND:指定Gunicorn绑定到的 server socket。

第13行和第14行将当前位置更改为项目目录并激活虚拟环境。

第16行至第24行使用指定的参数运行Gunicorn。

通过运行以下命令使其可执行:

chmod u+x gunicorn_start

在项目目录中创建一个文件夹 run ,用于存储您在参数中定义的Unix套接字文件BIND:

mkdir run
  1. 配置Supervisor

首先,在项目目录中创建一个名为 logs 的目录,用于存储应用程序的错误日志:
mkdir logs

接下来,通过运行以下命令创建 Supervisor 的配置文件:

sudo vim /etc/supervisor/conf.d/fastapi-app.conf

复制并粘贴以下内容到文件中:

[program:fastapi-app]
command=/home/fastapi-user/fastapi-nginx-gunicorn/gunicorn_start
user=fastapi-user
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/fastapi-user/fastapi-nginx-gunicorn/logs/gunicorn-error.log

此配置文件指定了之前创建的 gunicorn_start 脚本,并设置了 fastapi-user 作为用户。Supervisor 将在服务器启动时启动应用程序,并在应用程序失败时重新启动它。错误日志将记录在项目目录下 logs/gunicorn-error.log 文件中。

重新加载Supervisor配置并重启服务,通过运行以下命令:

sudo supervisorctl reread
sudo supervisorctl update

您可以通过运行以下命令检查程序的状态:

sudo supervisorctl status fastapi-app

如果一切顺利,fastapi-app 服务的状态应显示为 RUNNING。

打开新的终端窗口,连接到服务器,并使用以下命令发出GET请求来测试它:

curl --unix-socket /home/fastapi-user/fastapi-nginx-gunicorn/run/gunicorn.sock localhost

如果代码进行了更改,可以通过运行以下命令重新启动服务以应用更改:

sudo supervisorctl restart fastapi-app

现在有一个使用 Gunicorn 和 Uvicorn 作为ASGI服务器的应用程序。接下来,使用 NGINX 设置反向代理服务器。

五 配置NGINX

为项目创建一个新的 NGINX 配置文件:

sudo vim /etc/nginx/sites-available/fastapi-app

打开NGINX配置文件并粘贴以下内容:

upstream app_server {
    server unix:/home/fastapi-user/fastapi-nginx-gunicorn/run/gunicorn.sock fail_timeout=0;
}

server {
    listen 80;

    # add here the ip address of your server
    # or a domain pointing to that ip (like example.com or www.example.com)
    server_name XXXX;

    keepalive_timeout 5;
    client_max_body_size 4G;

    access_log /home/fastapi-user/fastapi-nginx-gunicorn/logs/nginx-access.log;
    error_log /home/fastapi-user/fastapi-nginx-gunicorn/logs/nginx-error.log;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        if (!-f $request_filename) {
            proxy_pass http://app_server;
            break;
        }
        }
}

工作原理如下:

第 1 行到第 3 行app_server定义了一个称为NGINX 将代理请求的服务器集群。请求被重定向到位于 的 Unix socket file /home/fastapi-user/fastapi-nginx-gunicorn/run/gunicorn.sock。设置fail_timeout=0告诉 NGINX 不要将服务器视为失败,即使它没有响应。

第 1 行到第 5 行定义了 NGINX 将用于处理请求的虚拟服务器的配置。在本例中,它侦听端口 80。将 XXXX 替换为 IP 或站点名称。

第 12 行和第 13 行指定keepalive_timeout设置客户端可以保持持久连接打开的最长时间,并client_max_body_size设置 NGINX 允许的客户端请求正文的大小限制。

第 15 行和第 16 行指定 NGINX 将写入其访问和错误日志的位置。

第 18 至 27 行定义了 NGINX 将如何处理对根目录的请求/。您提供一些规范来处理标头,并设置一个指令来将请求代理到您app_server之前定义的。

通过运行以下命令从文件创建符号链接来启用站点配置

sites-available:sites-enabled
sudo ln -s /etc/nginx/sites-available/fastapi-app /etc/nginx/sites-enabled/

测试配置文件是否正常并重启NGINX:

sudo nginx -tsudo systemctl restart nginx

现在应该已经运行了 FastAPI 应用程序,并且 Gunicorn + Uvicorn 作为 ASGI 服务器,NGINX 在它们前面作为反向代理。

如果出现权限错误,表示NGINX无法访问Unix socket,您可以将用户 www-data(通常是NGINX进程运行的用户)添加到fastapi-user组中。您可以使用以下命令:

sudo usermod -aG fastapi-user www-data

如果您已经有域名,请继续执行下一步以获取SSL证书并启用HTTPS。

使用 Certbot 获取免费 SSL 证书

这仅适用于您希望为其获取SSL证书的域名。如果您使用的是Ubuntu,则可以跳过此步骤。否则,您首先需要安装snapd:

sudo apt install snapd

接下来,确保您拥有最新可用版本:

sudo snap install core; sudo snap refresh core

安装Certbot并确保certbot命令可执行:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

接下来,通过以交互方式运行以下命令为您的域名生成证书:

sudo certbot --nginx

最后,Certbot将自动处理您证书的续订。要测试它是否有效,请运行以下命令:

sudo certbot renew --dry-run

现在,应该能够通过HTTPS成功发送请求。

结论

本篇文章介绍了如何使用 NGINX、Gunicorn 和 Uvicorn 来部署 FastAPI 应用程序。FastAPI 是最流行的 Python Web 框架之一。它已成为部署机器学习驱动的 Web 应用程序的首选,因此你希望持续关注AI领域,并希望能做一定的应用开发实践,熟悉它还是挺有帮助的。

原创文章。转载请注明: 作者:meixi 网址: https://www.icnma.com
Like (1)
meixi管理
Previous 12/10/2024 16:43
Next 06/04/2023 13:35

猜你想看