前言
之前发布的文章中提及到了,前段时间使用Fastapi重构了Java代码覆盖率服务统计工作,总之是本着学习Fastapi框架的理念,重构完成之后,就要部署了,那该如何部署呢?在本地部署和正式环境部署难道不一样吗?带着疑问我们一起来看看。
本地部署
本地开发调试过程中,我通常是这样启动Fastapi服务的
在终端中运行:
css
uvicorn main:app --host 0.0.0.0 --port 80
当然,也可以python脚本启动:
ini
import uvicorn
uvicorn.run(
app="main:app",
host="0.0.0.0",
port=8088,
reload=True
)
这样就好启动一个服务,reload=True支持热重载,方便调试。
应该是比较简单的,那到正式环境,为啥不使用uvicorn直接启动呢?是有更好的方式吗?
正式环境部署
在正式生产环境中,通常不直接使用 Uvicorn 来启动 FastAPI 应用,而是借助 Gunicorn 或者其他类似的 WSGI 服务器来处理请求。这是因为:
- 性能和稳定性: Gunicorn 是一个专门用于生产环境部署的 WSGI 服务器,具有更好的性能和稳定性,能够处理大量并发请求并自动进行负载均衡。
- 多进程支持: Gunicorn 支持多进程方式处理请求,通过调整 Worker 数量可以更好地利用多核 CPU 资源,提高并发处理能力。
- 日志和监控: Gunicorn 提供了更丰富的日志记录功能,便于监控应用程序的运行情况,并支持与其他日志系统集成,有利于故障排查和性能优化。
- 灵活性和扩展性: 使用 Gunicorn 可以方便地配置各种参数,调整工作模式、Worker 数量等,以适应不同规模和需求的应用程序。
终于引出了本文的主题,Gunicorn
Gunicorn
Gunicorn 是一个 Python WSGI HTTP 服务器,它允许运行Python的web应用程序。WSGI 是 Web Server Gateway Interface 的缩写,是 Python 应用程序与 Web 服务器之间的标准接口。
Gunicorn 的特点包括:
- 易用性:只需一个简单的命令即可启动服务。
- 兼容性:遵循 WSGI 标准,可以与大多数的Python web 框架协同工作。
- 性能优化:使用预分叉模型来减少工作负载,并提高性能。
- 并发处理:支持 gevent 和 asyncio 等异步工作模式,有效处理并发请求。
使用 Gunicorn 部署 FastAPI 应用
安装 Gunicorn
使用 pip 来安装:
pip install gunicorn
启动 Gunicorn 服务器
现在,我们使用 Gunicorn 来启动 FastAPI 应用
这里笔者的 FastAPI 应用文件名为 main.py
,并且 FastAPI 实例叫做 app
。
在终端中运行:
css
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
-w 4
指定了工作进程数为4。建议设置为当前机器CPU核心数的2-4倍。-k uvicorn.workers.UvicornWorker
设置工作类为 UvicornWorker,这样 Gunicorn 会知道它需要用 Uvicorn 来运行 ASGI 应用。
调整 Gunicorn 配置
可以通过改变命令行参数或使用配置文件来自定义 Gunicorn 的配置。
- -b, --bind :指明服务器绑定的地址。可以使用IP和端口号的组合(例如
127.0.0.1:8000
)或是 UNIX socket的路径。例如:gunicorn -b 0.0.0.0:8000 myapp:app
- -w, --workers :设置工作进程数。根据官方文档,通常设定为CPU核心数的2-4倍。例如:
gunicorn -w 4 myapp:app
- -k, --worker-class :工作模式选择。常见的有
sync
、gevent
、uvicorn.workers.UvicornWorker
等。指定uvicorn.workers.UvicornWorker
可以让 Gunicorn 支持 ASGI 应用,例如 FastAPI。例如:gunicorn -k uvicorn.workers.UvicornWorker myapp:app
- --threads :每个进程下线程的数量,仅限于
gthread
工作模式。这可以用于处理I/O密集型应用。例如:gunicorn --threads 2 myapp:app
- --timeout :设置工作进程的超时秒数。如果一个工作进程在此时间内未报告状态,它将被杀死并有新的工作进程启动。默认为30秒。例如:
gunicorn --timeout 120 myapp:app
- --max-requests :每个工作进程处理的最大请求数,之后会重启该工作进程。这有助于释放内存。例如:
gunicorn --max-requests 1000 myapp:app
- --daemon :开启守护进程模式,Gunicorn在后台运行。例如:
gunicorn --daemon myapp:app
- -c, --config :指向配置文件的路径。配置文件应为Python文件,其中包含Gunicorn设置。例如:
gunicorn -c /path/to/config.py myapp:app
- --access-logfile 和 --error-logfile :分别设置访问日志和错误日志的文件路径。使用
'-'
表示标准输出。例如:gunicorn --access-logfile - --error-logfile - myapp:app
- --log-level :日志级别的设置。有效的级别有 debug、info、warning、error 和 critical。例如:
gunicorn --log-level debug myapp:app
- --reload :如果代码有修改,自动重新启动工作进程,方便开发调试。不建议在生产环境中使用。例如:
gunicorn --reload myapp:app
或者使用gunicorn_conf.py
配置文件:
ini
import os
import multiprocessing
daemon=True # 设置守护进程
bind='0.0.0.0:8000' # 监听内网端口8000
chdir='./' # 工作目录
worker_class='uvicorn.workers.UvicornWorker' # 工作模式
workers=multiprocessing.cpu_count()+1 # 并行工作进程数 核心数*2+1个
threads=2 # 指定每个工作者的线程数
worker_connections = 2000 # 设置最大并发量
loglevel='debug' # 错误日志的日志级别
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
# 设置访问日志和错误信息日志路径
log_dir = "./log"
if not os.path.exists(log_dir):
os.makedirs(log_dir)
pidfile='./log/gunicorn.pid' # 设置进程文件目录
accesslog = "./log/gunicorn_access.log"
errorlog = "./log/gunicorn_error.log"
然后,使用命令:
css
gunicorn -c gunicorn_conf.py main:app
改造覆盖率服务正式环境部署
安装上面的方式,新建了gunicorn_conf.py文件,然后启动,我们看看效果
最后
使用 Gunicorn 部署你的 FastAPI 应用。它不仅提供了一个高性能的服务器环境,还让你可以灵活地配置多个选项,以满足生产环境的需求。