zl程序教程

您现在的位置是:首页 >  其他

当前栏目

使用gunicorn部署flask服务

部署服务 Flask Gunicorn 使用
2023-09-11 14:17:50 时间

为什么要用gunicorn部署flask

当我们以production环境运行flask项目时,通常flask会在控制台打印出一个警告:“WARNING: Do not use the development server in a production enviroment. Use a production WSGI server instead.”什么意思,简单的说就是flask只为我们提供了一个用于开发环境的WSGI容器,当部署到生产环境时请使用一个用于生产环境的WSGI容器来替代。那有哪些可用于生产环境的WSGI容器呢,现在比较常用的有gunicorn和uWSGI,两者性能差不多,但gunicorn使用起来更简单。

在使用flask开发web时,flask并不是简单的为我们提供了一个web框架,还为我们提供了一个简易的WSGI容器。WSGI(Web Server Gateway Interface)服务器网关接口,它就像一条纽带,将web服务器与web框架连接起来。gunicorn也是一个WSGI容器,但相比flask为我们提供的WSGI容器,一个高富帅,一个矮穷挫。在我们开发web时,使用flask为我们提供的WSGI容器进行调试没有任何问题,但当需要部署我们的flask项目到服务器上时,flask提供的WSGI容器就无法提供我们想要的性能了。比如在一个16核的服务器中,如果单用flask运行,我们查询后台的python进程就一个,但如果使用gunicorn+flask进行部署(假设在gunicorn中设置的进程数为16),我们查询后台的python进程就有17个(一个监控进程,16个运行进程),这样就能够让flask充分的利用服务器的性能资源。下面简单介绍gunicorn的使用流程。

gunicorn的安装

本实例安装的是gunicorn 20.0.2

# pip 安装
pip install gunicorn

# 如果使用的是anaconda,建议使用conda安装
conda install gunicorn

gunicorn配置与使用

首先我们先做下简单的配置,进入到你的flask项目根目录中,新建一个gconfig.py文件,写入以下代码:

import os
from gevent import monkey
monkey.patch_all()

import multiprocessing

# debug
debug = True
loglevel = 'debug'
bind = '0.0.0.0:5000'
if not os.path.exists("./log"):
    os.makedirs("./log")
pidfile = "log/gunicorn.pid"
accesslog = "log/access.log"
errorlog = "log/debug.log"
daemon = True

# 启动进程数
workers = multiprocessing.cpu_count()
worker_class = "gevent"
x_forwarded_for_header = "X-FORWARDED-FOR"

我们设置debug模式,在运行时会打印出我们的所有配置信息,写在log/debug.log文件中,bind就是监听的地址以及端口号,access.log会记录所有的请求服务者的信息。daemon参数表示是否在后台运行,为true时为后台运行,这样就不需要使用nohub指令了,比较方便。workers就是开启的进程数,worker_class为gevent,gevent是python的第三方库,通过gevent能够轻松的实现并发同步或异步编程。如果没有安装gevent的话需要手动安装以下(gunicorn 20.0.2要求的gevent版本在1.4.0以及以上),否则运行gunicorn会报错。

配置完成后在flask项目根目录中启动终端,输入以下指令进行启动gunicorn(gconfig.py是我们刚建立的配置文件,我的flask项目入口是app.py,如果你的入口是run.py则改成run:app):

gunicorn -c gconfig.py app:app

启动后我们打开log/debug.log文件可以看到所有的配置信息,如果该文件中没有报错信息,则说明启动成功。

我们通过以下指令查看gunicorn进程树:

pstree -ap | grep gunicorn

包括一个主进程(一般是进程树的第一个进程),和一系列子进程。主进程是一个守护进程,会监控所有的子进程的状态,每个子进程就是一个flask服务。如果需要关闭gunicorn,直接kill主进程的pid就行了。

# 关闭gunicorn,假设主进程pid为123456
kill -9 123456

# 重启服务
kill -HUP 123456