FastAPI 工程管理(三) 工程部署

作者:麦克煎蛋   出处:https://www.cnblogs.com/mazhiyong/ 转载请保留这段声明,谢谢!

我们这里不使用容器进行部署。使用容器部署可参考:https://fastapi.tiangolo.com/deployment/

一、安装ASGI兼容Server

我们选择Uvicorn作为ASGI Server。

Uvicorn,是一个闪电般快速的ASGI服务器,基于uvloop和httptools构建。

pip install uvicorn

Uvicorn可按以下方式运行我们的应用:

uvicorn main:app --host 0.0.0.0 --port 80
INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)

二、使用进程管理器

pip install guvicorn

使用进程管理器确保以弹性方式运行运行多个进程。一个进程管理器将会处理套接字设置,启动多个服务器进程,监控进程活动,监听进程重启、关闭等信号。

Uvicorn 提供一个轻量级的方法来运行多个工作进程,比如 `--workers 4`,但并没有提供进程的监控。

Gunicorn 是成熟的,功能齐全的服务器,Uvicorn 内部包含有 Guicorn 的 workers 类,允许你运行 ASGI 应用程序,这些 workers 继承了所有 Uvicorn 高性能的特点。

使用 Guicorn 来进行进程管理,我们可以动态增加或减少进程数量,平滑地重启工作进程,或者升级服务器而无需停机。

在生产环境中,Guicorn 大概是最简单的方式来管理 Uvicorn 了,生产环境部署我们推荐使用 Guicorn 和 Uvicorn 的 worker 类:

gunicorn example:app -w 4 -k uvicorn.workers.UvicornWorker

执行上述命令将创建 4 个工作进程,其中 UvicornWorker的实现使用 uvloop 和httptools 实现。

Gunicorn 为 Uvicorn 提供了不同的配置选项集,但是一些配置暂不支持,如--limit-concurrency

三、部署实践

工程目录结构如下:

├── app
│   ├── __init__.py (程序入口)
│   └── routers
│       ├── __init__.py
│       ├── items.py
│       └── users.py
├── run.py (服务器运行入口)
├── local.py (本地运行入口)
├── gunicorn.py (Gunicorn设置信息)

1、修改程序入口文件

将初始化代码放到app目录下的__init__.py文件中:

import os
from fastapi import Depends, FastAPI, Header, HTTPException

from .routers import items, users
def create_app():
    """Create and configure an instance of the Flask application."""
    app = FastAPI()

    async def get_token_header(x_token: str = Header(...)):
        if x_token != "fake-super-secret-token":
            raise HTTPException(status_code=400, detail="X-Token header invalid")

    app.include_router(users.router)
    app.include_router(
        items.router,
        prefix="/items",
        tags=["items"],
        dependencies=[Depends(get_token_header)],
        responses={404: {"description": "Not found"}},
    )

    return app

2、添加启动文件

local.py

from app import create_app

app = create_app()

在开发环境下,通过以下命令启动应用:

uvicorn local:app --reload

run.py

from app import create_app
import logging
from fastapi.logger import logger as fastapi_logger
from logging.handlers import RotatingFileHandler

app = create_app()


# 将日志保存到文件中
formatter = logging.Formatter(
    "[%(asctime)s.%(msecs)03d] %(levelname)s [%(thread)d] - %(message)s", "%Y-%m-%d %H:%M:%S")
handler = RotatingFileHandler('/data/log/abc.log', backupCount=0)
logging.getLogger().setLevel(logging.NOTSET)
fastapi_logger.addHandler(handler)
handler.setFormatter(formatter)

fastapi_logger.info('****************** Starting Server *****************')

Gunicorn配置文件(gunicorn.py)

 # Gunicorn的配置可以参考:

 # https://blog.csdn.net/y472360651/article/details/78538188

 # https://docs.gunicorn.org/en/stable/settings.html#server-mechanics


debug = True daemon = True bind = '0.0.0.0:9000' # 绑定ip和端口号 # backlog = 512 # 监听队列 chdir = '/data/fastest' # gunicorn要切换到的目的工作目录 timeout = 30 # 超时 # worker_class = 'gevent' #使用gevent模式,还可以使用sync 模式,默认的是sync模式 work_class = 'uvicorn.workers.UvicornWorker' # workers = multiprocessing.cpu_count() * 2 + 1 # 进程数 # threads = 2 #指定每个进程开启的线程数 loglevel = 'debug' # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置 access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"' # 设置gunicorn访问日志格式,错误日志无法设置 """ 其每个选项的含义如下: h remote address l '-' u currently '-', may be user name in future releases t date of the request r status line (e.g. ``GET / HTTP/1.1``) s status b response length or '-' f referer a user agent T request time in seconds D request time in microseconds L request time in decimal seconds p process ID """
# 如果使用service启动,这里的pid路径应与service的pid路径保持一致,否则无法启动 pidfile
= "/data/log/fast.pid"

accesslog = "/data/log/gunicorn_fasttest_access.log" # 访问日志文件 errorlog = "/data/log/gunicorn_fasttest_error.log" # 错误日志文件

3、生产环境启动应用

通过脚本可以自动拉取或更新代码到部署目录,然后切换到部署目录下,即可通过以下命令管理应用:

systemctl  start/stop/restart gunicorn_fast.service

gunicorn_fast.service内容如下:

[Unit]
Description=Gunicorn fast
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking

PIDFile=/data/log/fast.pid

# 这里使用了虚拟环境下的Gunicorn ExecStart
=/root/.virtualenvs/ppcms/bin/gunicorn -c /data/fastest/gunicorn.py run:app ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target

4、nginx层

用户访问首先到达nginx层,然后再向后端转发,详细部署暂略。

猜你喜欢

转载自www.cnblogs.com/mazhiyong/p/13384785.html