文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python之gunicorn的配置

2023-09-11 21:26

关注

为了实现并发,python常见的web部署搭配nginx + gunicorn, flask + gunicorn

本文介绍gunicorn的配置和使用。

1. 安装gunicorn

pip install gunicorngunicorn -h  # 查看使用的命令直接使用 gunicorn 命令可能会报,可以查找到gunicorn文件以绝对路径添加环境变量 vi /etc/profile最底下添加:PATH="$PATH:/usr/local/bin"  export PATH引用环境变量:source /etc/profile

2. gunicorn启动一个flask的应用程序  

1. 配置flask路由 (my_service.py )

# my_service.py# !/usr/bin/env python# -*- coding:utf8 -*-# Desc:  http路由import jsonfrom flask import Flask from MyLogObj import *   #日志app = Flask(__name__)app.config['DEBUG'] = Truemy_methods=["GET","POST"]@app.route('/')def index():    print("--------1----------")    return '请求成功'@app.route('/error')def index_error():    print("--------error----------")    a = 'assss'    json.loads(a)    return '请求失败'@app.route('/logtest')def index_logtest():    try:        print("--------logtest----------")        a = 'assss111'        json.loads(a)    except Exception as e:        mlog.error('read conffile[%s] except' % CONF_FILE)        mlog.info('read conffile[%s] except info ' % CONF_FILE)    return '请求失败logtest'if __name__ == '__main__':    app.run(host='127.0.0.1',port=8001)
# -D后台启动,第一个my_service指的是my_service.py文件,第二个指的是py里flask应用的名字; gunicorn -D -w 4 -b 0.0.0.0:8000 my_service:app 

3. 配置文件的方式

1 全局配置文件 

# config.ini [MySQL]DB_HOST=127.0.0.1DB_PORT=3306DB_USER=rootDB_PASSWRD=pwd123DB_DATABASE=dbtestMAX_USAGE=10MIN_CACHED=1MAX_CACHED=10CHARSET=utf8[RUN]thread=10processor=20[LOG_CONF]log_level = DEBUGstdin=0datefmt = %a, %d %b %Y %H:%M:%Slog_file = log.logmaxSize = 10*1024*1024

2 读取配置文件

# MySetting.py# !/usr/bin/env python# -*- coding=utf-8 -*-import platformimport cgiimport configparser#错误码SUCCESS = 0           #成功PARA_FAILED = 1       #参数错误USER_INFO_ERROR = 3 #用户信息错误Access_Control ='http://localhost:8001'if platform.system() == 'Linux':    base_path = '/home/guntest/'    CONF_FILE = base_path + 'conf/config.ini'    Dir_partition = '/'    UPLOADS_PATH=base_path + 'uploads/'    IMG_PATH=base_path + 'img/'else:    base_path = 'G:\\guntest\\'    CONF_FILE = base_path + 'conf\\config.ini'    Dir_partition = '\\'    UPLOADS_PATH = base_path + 'uploads\\'    IMG_PATH=base_path + 'img\\'

3 配置flask路由 (gunicorn_service.py )

# gunicorn_service.py# !/usr/bin/env python# -*- coding:utf8 -*-# Desc: linux start self service by gunicorn# !/usr/bin/env python# -*- coding:utf8 -*-from werkzeug.middleware.proxy_fix import ProxyFixfrom my_service import *import geventapp.wsgi_app = ProxyFix(app.wsgi_app)

4 配置 my-gun.conf 

import osbind = '127.0.0.1:8001'#bind = '0.0.0.0:8001'workers = 2user="root"worker_class="gevent" #sync, geventbacklog = 2048daemon = Truedebug = Trueproc_name = 'gunicorn-self.proc'# 服务进程 pidfile = '/home/zyy/log/my-gunicorn.pid'# 访问日志路径accesslog = '/home/zyy/log/gunicorn_access.log'# 错误信息日志路径errorlog = '/home/zyy/log/gunicorn_error.log'# 设置日志记录水平loglevel = 'info'   #warning

5 日志配置

#MyLogObj.py #globlsfrom MyLog import *mlog = my_logger().GetInstance(None, "guntest-service")
# MyLog.py#!/usr/bin/env python#-*- coding:utf-8 -*-#Author: zyy#Date:2023-06-18#Desc:log classimport loggingfrom MySetting import *instance_logger = Noneclass  my_logger:    def __init__(self):        pass    def GetInstance(self, confile, modname):        global instance_logger        if None == instance_logger:            if None == confile or '' == confile:                confile = CONF_FILE            conf = configparser.ConfigParser()            conf.read(confile)            file_path = "%slog%s%s"%(base_path, Dir_partition, conf.get('LOG_CONF', 'log_file'))            logger=logging.getLogger(modname)            fh = logging.FileHandler(file_path)            stdin = conf.get('LOG_CONF', 'stdin')            if stdin == '1':                ch = logging.StreamHandler()            level = conf.get('LOG_CONF','log_level')            if level == None or level == '' or level == 'DEBUG':                logger.setLevel(logging.DEBUG)                fh.setLevel(logging.DEBUG)            if level == 'INFO':                logger.setLevel(logging.INFO)                fh.setLevel(logging.INFO)            if level == 'WARNING':                logger.setLevel(logging.WARNING)                fh.setLevel(logging.WARNING)            if level == 'ERROR' :                logger.setLevel(logging.ERROR)                fh.setLevel(logging.ERROR)            if level == 'CRITICAL':                logger.setLevel(logging.CRITICAL)                fh.setLevel(logging.CRITICAL)            formatter = logging.Formatter("[%(asctime)s][%(filename)s:%(lineno)d][%(levelname)s]:%(message)s")            if stdin == '1':                ch.setFormatter(formatter)            fh.setFormatter(formatter)            logger.addHandler(fh)            if stdin == '1':                logger.addHandler(ch)            instance_logger = logger        return instance_loggerif __name__ == '__main__':    log1 = my_logger().GetInstance(None, "log1")    log2 = my_logger().GetInstance(None, "log2")    log3 = my_logger().GetInstance(None, "log3")    log1.debug('this is debug')    log2.debug('this is debug')

6 启动文件  start.sh  (chmod 777 start.sh)

#!/bin/sh#coding:utf8#gunicorn envsource /etc/profileSERVER_HOME="/home/zyy/zyy_test"echo '---1----'SELF_SERVER_EXECUTE="my-gun.conf my_service:app"SELF_SERVER_NAME="my_service"SELF_EXECUTE="gunicorn -c my-gun.conf my_service:app"echo '---2----'check_self_pid(){        echo ` ps -efww | grep -v 'grep' | grep "${SELF_SERVER_EXECUTE}" | awk '{print $2}' `}start_self(){        pid=$(check_self_pid)        if [ -n "$pid" ]; then                echo "Warning: $SELF_SERVER_NAME already started! (pid: $pid)"        else                echo -n "Starting $SELF_SERVER_NAME ..."                cd $SERVER_HOME                $SELF_EXECUTE                sleep 1                pid=$(check_self_pid)                if [ -n "$pid" ]; then                        echo "(pid: $pid) [OK]"                else                        echo "[Failed]"                fi        fi}start(){        start_self}stop_self(){        pid=$(check_self_pid)        if [ -n "$pid" ]; then                echo -n "Stopping $SELF_SERVER_NAME ...(pid: $pid)"                kill $pid &>/dev/null                sleep 1                pid=$(check_self_pid)                if [ -z "$pid" ]; then                        echo "[OK]"                else                        echo "[Failed]"                fi        else                echo "Warning: $SELF_SERVER_NAME is not running"        fi}stop(){        stop_self}case "$1" in        'start')                start                ;;        'stop')                stop                ;;        'restart')                stop                start                ;;        *)                echo "Usage: $0 {start|stop|restart}"                exit 1esac

7 启动 

./start.sh start  #启动./start.sh restart  #重启./start.sh stop  #停止

到这里就结束了,以下部分是参数详解,可根据需要自行配置

4. gunicorn的参数详解

1 参数

-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: 设置环境变量;

2 配置文件参数

# gunicorn.conf# 并行工作进程数workers = 4# 指定每个工作者的线程数threads = 2# 监听内网端口5000bind = '127.0.0.1:5000'# 设置守护进程,将进程交给supervisor管理daemon = 'false'# 工作模式协程worker_class = 'gevent'# 设置最大并发量worker_connections = 2000# 设置进程文件目录pidfile = '/var/run/gunicorn.pid'# 设置访问日志和错误信息日志路径accesslog = '/var/log/gunicorn_acess.log'errorlog = '/var/log/gunicorn_error.log'# 设置日志记录水平loglevel = 'warning'

3 由于windows平台不支持gunicorn,gunicorn安装成功后,启动会出现

‘ImportError: No module named _curses / fcntl’错误;需要下载fcntl.py文件;

参考:

python之gunicorn的配置_modulenotfounderror: no module named 'pwd_黑色小米粥的博客-CSDN博客

来源地址:https://blog.csdn.net/cocos2dGirl/article/details/131305329

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯