前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[1269]使用gunicorn部署flask项目

[1269]使用gunicorn部署flask项目

作者头像
周小董
发布2024-03-10 08:08:24
2710
发布2024-03-10 08:08:24
举报
文章被收录于专栏:python前行者python前行者

1、简介

flask 自带的web服务器可用于开发环境运行调试,不适合部署在生产环境,无法满足线上的性能要求。当使用app.run(host = '0.0.0.0',port=6000)启动时,flask框架会有一段 WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.

先介绍下几个概念,方便理解使用 wsgi server 部署的意义:

  • WSGI: 全称是Web Server Gateway Interface(web服务器网关接口),它是一种规范,它是web服务器和web应用程序之间的接口。它的作用就像是桥梁,连接在web服务器和web应用框架之间。
  • uwsgi: 是一种传输协议,用于定义传输信息的类型。
  • uWSGI: 是实现了uwsgi协议WSGI的web服务器。

gunicorn是一个python WSGI http server,我们这里采用它做 wsgi 服务器,来部署flask程序。

2、模块安装

代码语言:javascript
复制
pip install gunicorn

一般使用它,主要是为使用其异步的worker模型,还需要安装对应的异步模块。

代码语言:javascript
复制
pip install greenlet # 使用异步必须安装
pip install eventlet # 使用eventlet workers
pip install gevent   # 使用gevent workers

3、启动命令

3.1 命令行配置 gunicorn 参数

gunicorn 命令启动程序比较简单。以下面 main.py 为例

代码语言:javascript
复制
from flask import Flask

app = Flask(__name__)

@app.route('/',methods=['GET'])
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=6000)

运行命令:

代码语言:javascript
复制
gunicorn -w 5 -b 0.0.0.0:6000 -t 120 main:app

持久化运行,使用nohup,运行日志将存储于当前目录的app.log日志

代码语言:javascript
复制
nohup python -m gunicorn -w 5 -b 0.0.0.0:6000 -t 120 main:app > app.log 2>&1 &

解释下参数含义:

  • -w:表示工作进程数
  • -b :访问地址和端口
  • -t:设置超时时间120秒,默认30秒
  • main :flask启动python文件名
  • app :脚本中创建的Flask对象名

注意:1、windows系统会报错:ModuleNotFoundError: No module named 'fcntl',原因是 gunicorn 不支持windows,在 linux 上可正常运行。

2、若遇到flask启动后,访问请求很慢,一般是 gunicorn 和 flask-socketio 版本不兼容,找到对应版本即可,我安装的都是最新版,没有问题。

如果生产环境,必不可少还需要配置日志信息,如下:

代码语言:javascript
复制
gunicorn -w 4 -b 0.0.0.0:8080 --access-logfile access.log --error-logfile error.log app:app -D

-D表示将gunicorn置于后台运行,可以通过tail -f access.log或者tail -f error.log查看记录的日志信息。

3.2 一些其他的Gunicorn命令示例
  • 运行一个名为myapp.py的Flask应用程序,启用访问日志和错误日志:
代码语言:javascript
复制
gunicorn --access-logfile access.log --error-logfile error.log myapp:app
  • 运行一个名为myapp.py的Flask应用程序,以守护进程模式运行:
代码语言:javascript
复制
gunicorn -D myapp:app
  • 运行一个名为myapp.py的Flask应用程序,指定配置文件:
代码语言:javascript
复制
gunicorn -c gunicorn.conf.py myapp:app
  • 重新加载正在运行的Gunicorn实例(平滑重启):
代码语言:javascript
复制
kill -HUP <主进程ID>
  • 停止正在运行的Gunicorn实例(优雅停止):
代码语言:javascript
复制
kill -TERM <主进程ID>
  • 运行一个名为myapp.py的Flask应用程序,设置工作进程的最大请求数:
代码语言:javascript
复制
gunicorn --max-requests 1000 myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置工作进程的最大请求数波动范围:
代码语言:javascript
复制
gunicorn --max-requests-jitter 50 myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置工作进程的名称前缀:
代码语言:javascript
复制
gunicorn --worker-tmp-dir /dev/shm myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置工作进程的临时目录:
代码语言:javascript
复制
gunicorn --worker-tmp-dir /dev/shm myapp:app
  • 运行一个名为myapp.py的Flask应用程序,启用SSL支持:
代码语言:javascript
复制
gunicorn --certfile=server.crt --keyfile=server.key myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置日志记录级别:
代码语言:javascript
复制
gunicorn --log-level debug myapp:app
  • 运行一个名为myapp.py的Flask应用程序,启用代理协议支持:
代码语言:javascript
复制
gunicorn --proxy-protocol myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置请求头大小限制:
代码语言:javascript
复制
gunicorn --limit-request-line 8190 myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置请求字段数量限制:
代码语言:javascript
复制
gunicorn --limit-request-fields 100 myapp:app
  • 运行一个名为myapp.py的Flask应用程序,设置请求字段大小限制:
代码语言:javascript
复制
gunicorn --limit-request-field_size 8190 myapp:app

请注意,上面的命令中的myapp:app表示您的应用程序位于名为myapp.py的文件中,并且Flask应用程序实例的名称为app。您需要根据您自己的应用程序进行相应修改。

3.3 文件配置 gunicorn 参数
3.3.1进程+线程模式

根目录新建配置文件 config.py

代码语言:javascript
复制
# 是否开启debug模式
debug = True
# 访问地址
bind = "0.0.0.0:6000"
# 工作进程数
workers = 2
# 工作线程数
threads = 2
# 超时时间
timeout = 600
# 输出日志级别
loglevel = 'debug'
# 存放日志路径
pidfile = "log/gunicorn.pid"
# 存放日志路径
accesslog = "log/access.log"
# 存放日志路径
errorlog = "log/debug.log"
# gunicorn + apscheduler场景下,解决多worker运行定时任务重复执行的问题
preload_app = True

运行命令:

代码语言:javascript
复制
gunicorn -c config.py main:app

看到以下信息表示启动成功

配置文件参数详解:

代码语言:javascript
复制
-c CONFIG    : CONFIG,配置文件的路径,通过配置文件启动;生产环境使用;

-b ADDRESS   : ADDRESS,ip加端口,绑定运行的主机;

-w INT, --workers INT:用于处理工作进程的数量,为正整数,默认为1;

-k STRTING, --worker-class STRTING:要使用的工作模式,默认为sync异步,可以下载eventlet和gevent并指定

--threads INT:处理请求的工作线程数,使用指定数量的线程运行每个worker。为正整数,默认为1。

--worker-connections INT:最大客户端并发数量,默认情况下这个值为1000。

--backlog int:未决连接的最大数量,即等待服务的客户的数量。默认2048个,一般不修改;

-p FILE, --pid FILE:设置pid文件的文件名,如果不设置将不会创建pid文件

--access-logfile FILE   :  要写入的访问日志目录

--access-logformat STRING:要写入的访问日志格式

--error-logfile FILE, --log-file FILE  :  要写入错误日志的文件目录。

--log-level LEVEL   :   错误日志输出等级。

--limit-request-line INT   :  HTTP请求头的行数的最大大小,此参数用于限制HTTP请求行的允许大小,默认情况下,这个值为4094。值是0~8190的数字。

--limit-request-fields INT   :  限制HTTP请求中请求头字段的数量。此字段用于限制请求头字段的数量以防止DDOS攻击,默认情况下,这个值为100,这个值不能超过32768

--limit-request-field-size INT  :  限制HTTP请求中请求头的大小,默认情况下这个值为8190字节。值是一个整数或者0,当该值为0时,表示将对请求头大小不做限制

-t INT, --timeout INT:超过这么多秒后工作将被杀掉,并重新启动。一般设定为30秒;

--daemon: 是否以守护进程启动,默认false;

--chdir: 在加载应用程序之前切换目录;

--graceful-timeout INT:默认情况下,这个值为30,在超时(从接收到重启信号开始)之后仍然活着的工作将被强行杀死;一般使用默认;

--keep-alive INT:在keep-alive连接上等待请求的秒数,默认情况下值为2。一般设定在1~5秒之间。

--reload:默认为False。此设置用于开发,每当应用程序发生更改时,都会导致工作重新启动。

--spew:打印服务器执行过的每一条语句,默认False。此选择为原子性的,即要么全部打印,要么全部不打印;

--check-config   :显示现在的配置,默认值为False,即显示。

-e ENV, --env ENV: 设置环境变量;
3.3.2进程+协程模式

根目录新建配置文件 config.py

代码语言:javascript
复制
from gevent import monkey
monkey.patch_all()

# 是否开启debug模式
debug = True
# 访问地址
bind = "0.0.0.0:6000"
# 工作进程数
workers = 2
# 设置协程模式
worker_class="gevent"  
# 最大客户端并发数量,默认情况下这个值为1000。此设置将影响gevent和eventlet工作模式
worker_connections=500
# 超时时间
timeout = 600
# 输出日志级别
loglevel = 'debug'
# 存放日志路径
pidfile = "log/gunicorn.pid"
# 存放日志路径
accesslog = "log/access.log"
# 存放日志路径
errorlog = "log/debug.log"
# gunicorn + apscheduler场景下,解决多worker运行定时任务重复执行的问题
preload_app = True

运行命令:

代码语言:javascript
复制
gunicorn -c config.py main:app

看到 using worker :gevent 模式启动

使用 gunicorn 部署到 docker 容器也比较方便,只要将启动命令写到 dockerfile 里即可。

其它可配置项:config.py

代码语言:javascript
复制
import logging
import logging.handlers
import os
import multiprocessing
import gevent.monkey
gevent.monkey.patch_all()

bind = '0.0.0.0:8080'  # 绑定的ip已经端口号
chdir = '/home/flaskProject'  # gunicorn要切换到的目的工作目录
timeout = 60  # 超时
worker_class = 'gevent'  # 使用gevent模式,还可以使用sync 模式,默认的是sync模式
workers = multiprocessing.cpu_count() * 2 + 1  # 启动的进程数
loglevel = "info"  # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'  # 设置gunicorn访问日志格式,错误日志无法设置
pidfile = "gunicorn.pid"
accesslog = "access.log"
errorlog = "error.log"
daemon = True  # 是否后台运行

启动后项目的目录下会生成access.log,error.loggunicorn.pid三个文件,gunicorn.pid中保存了gunicorn的主进程PID号,可以通过cat gunicorn.pid查看,当想要停止gunicorn时,直接kill 进程号即可杀死所有gunicorn进程。

4、结束gunicorn服务进程

使用ps -ef | grep gunicorn命令找出gunicorn所有进程。

代码语言:javascript
复制
[root@VM_0_12_centos ~]# ps -ef | grep gunicorn
root     16843 23035  0 Oct14 ?        00:00:02 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
root     22445 23035  0 Oct04 ?        00:00:15 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
root     22581 23035  0 Oct11 ?        00:00:05 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
root     23035     1  0 Sep27 ?        00:04:11 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app

然后使用 kill -9 进程ID 命令来杀掉进程,注意,我们找到主进程杀掉即可,子进程会随之结束,在上例中,主进程号为23035.

代码语言:javascript
复制
[root@VM_0_12_centos ~]# kill -9 23035
[root@VM_0_12_centos ~]# ps -ef | grep gunicorn

杀掉进程后,稍等几秒,再使用ps -ef | grep gunicorn查看,发现gunicorn服务进程已全部杀掉。

参考:https://www.cnblogs.com/shenh/p/16824903.html https://blog.csdn.net/Woodrow1994/article/details/113831985 https://zhuanlan.zhihu.com/p/618533248 https://zhuanlan.zhihu.com/p/488458470 http://www.manongjc.com/detail/12-nhpgmgnknsiysxf.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、简介
  • 2、模块安装
  • 3、启动命令
    • 3.1 命令行配置 gunicorn 参数
      • 3.2 一些其他的Gunicorn命令示例
        • 3.3 文件配置 gunicorn 参数
          • 3.3.1进程+线程模式
          • 3.3.2进程+协程模式
      • 4、结束gunicorn服务进程
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档