Linux搭建Flask + Nginx + Gunicorn + Gevent

今天在阿贝云申请了个免费的服务器,感觉还不错,有5m的小水管和40g云盘,免费的还要啥自行车,刚好拿来练习下python网站框架

准备工作

需要安装的依赖

  • Nginx
  • Gunicorn
  • Gevent

部署是建立在你已经基本完成开发的基础上,所以Python的安装什么的就不再进行说明了,上述依赖的安装也不再赘述,请根据自己的平台查找安装教程,这里主要对配置进行说明。

Gunicorn的配置

Gunicorn的配置相比于uWSGI简单了很多,基本上一行命令就可以把项目跑起来。性能上据说uWSGI更加强大一些,不过在差距上并不明显, 至少在我的日常使用中没有因为Gunicorn出现过性能瓶颈,真的到了那一天再进行更换也不是什么特别麻烦的事情。

创建Gunicorn配置文件

在项目跟目录创建一个gunicorn.py文件,当然名字和文件位置你可以进行更改。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gevent.monkey

gevent.monkey.patch_all()

import multiprocessing
import os

if not os.path.exists('log'):
    os.mkdir('log')

debug = True
loglevel = 'debug'
bind = '127.0.0.1:8000'
pidfile = 'log/gunicorn.pid'
logfile = 'log/debug.log'
errorlog = 'log/error.log'
accesslog = 'log/access.log'

# 启动的进程数
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'gunicorn.workers.ggevent.GeventWorker'

x_forwarded_for_header = 'X-FORWARDED-FOR'

这里我们采用gevent模式来支持并发,可以根据你自己的实际情况来进行模式选择。我最近的项目因为阻塞主要是对SAP数据查询导致的,所使用的库并不是纯Python编写,也没有说明支持协程,所以我我采用了gthead模式。

首先我们调用了gevent的Monkey Patch黑科技,该方法hook了标准卡里面的大部分阻塞操作,使得在我们进行长时间IO操作时可以切换到别的协程,从而实现异步并发。然后我们创建log目录,设置log路径,设置端口什么的。

接着我们设置worker的数量,也就是进程数,通常设置为服务器核心数2倍+1,这也是官方文档事例中的配置。最后再设置一下worker的模式,这里填写的就是前文所说的gevent。

更多项目配置请参照官方文档
Configuration Overview — Gunicorn 20.1.0 documentation

创建另一个程序入口

不管你是用flask-script还是flask-cli来启动项目,一定会有一个入口文件(这名字一定很不规范),里面创建并启动了Flask App实例。这里再创建一个程序入口,这个入口专门为Gunicorn服务,用来启动生产环境。

再根目录创建一个wsgi.py文件,名字目录还是可以随意更改。

from app.application import create_app
from app.config_prod import Config
import logging

application = create_app(Config)
gunicorn_logger = logging.getLogger('gunicorn.error')
application.logger.handlers = gunicorn_logger.handlers
application.logger.setLevel(gunicorn_logger.level)

if __name__ == '__main__':
    application.run()

这里和你普通的程序入口并没有什么区别,中间对logger的一顿操作是把app的logger修改为gunicorn的,这样我们再上一步设置的log路径才能生效。

测试gunicorn配置文件

测试配置是否正确最简单的方法就是跑一下。
如果你是用了虚拟环境,首先要先进入虚拟环境(这里强烈建议使用虚拟环境,我还是使用传统的virtualenv)。

然后执行命令:

gunicorn -c gunicorn.py wsgi:application

gunicorn.py和wsgi:application根据前两部的文件名和变量名自行更改

Uninx哲学,没有消息就是最好的消息,如果没有报错,程序就顺利跑起来了。这时如果有图形界面或者设置的端口是开放给外网的,你就可以访问项目试试看是否成功运行,如果无法通过外网访问并没有图形界面,也可以通过wget命令进行测试,请确保这个步骤正确再进行下一步操作。如果这一步顺利完成,就可以Ctrl+C退出了,因为我们不需要手动启动项目,接下来我们将通过Supervisor来帮助我们管理项目的进程。

配置Supervisor

Supervisor是一个用Python编写的进程管理工具,我们这里通过他来管理我们的项目进程,开启关闭啥的。

首先检查是否存在配置文件,一般配置文件的路径是

/etc/supervisord.conf

如果配置文件不存在,我们可以通过命令来生成

echo_supervisord_conf > /etc/supervisord.conf

配置文件的内容很多,项目配置可以参照官网文档
Introduction — Supervisor 4.2.4 documentation

打开配置文件的最后一行

;[include]
;files = /etc/supervisord/*.conf

默认一般是注释掉的,我们可以取消注释,这行配置的作用也很浅显,就是导入设置的路径下的所有conf文件,这使得我们如果有多个项目可以不用都写在同一个配置文件里,可以一个项目一个配置文件,更适合管理。这里的路径也是可以按照实际需求随意更改。这里需要重启Supervisor服务,我刚开始做的时候都是直接重启服务器,不过如果你没有把Supervisor自启动,重启后需要手动启动Supervisord

supervisord -c /etc/supervisord.conf

在设置的路径下新建一个配置文件,命令请根据上一步设置的扩展名。

[program:project_name]
command=/project_path/venv/bin/gunicorn -c gunicorn.py wsgi:application
directory=/project_path/
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true

project_name按照你的实际需求修改,作为你这个服务的唯一标识,用于启动停止服务时使用。
command修改为测试gunicorn时使用的命令,这里我因为使用了虚拟环境,所以我使用了绝对路径,指向了虚拟环境的gunicorn,这种配置我个人还是喜欢都使用绝对路径。
directory指定了工作路径,通常设置为项目根目录,我们填写的gunicorn.py和wsgi都是基于这个路径的。

更多配置请参照官网的配置文档。

管理Supervisor的项目是使用supervisorctl命令,我们可以启动项目试试看

supervisorctl start project_name

如果没有报错,应该可以和上一步测试gunicorn一样可以正常访问项目了。

Nginx配置

Nginx的各种好处就自行查询吧,我们这里就做一下简单的配置。
因为我的项目一般都是前后端分离的,所以这里这里还会配置CORS来解决跨域的问题

这里就不细说了,整段贴出来,说一下其中一些重点

server {
        listen 80;

        root /home/iws_admin/IWS_WX_API;
        index index.html index.htm;

        # Make site accessible from http://localhost/
        server_name dev.wlafit.com;

        location / {
                add_header Access-Control-Allow-Origin * always;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
                add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

                if ($request_method = 'OPTIONS') {
                   return 204;
                }

                proxy_pass       http://127.0.0.1:5000;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_redirect off;
                proxy_set_header Host $host:80;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

add_header相关设置主要是CORS,解决跨域的

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

第一第二行末尾加了always作用是默认CORS只对2XX状态码有效,如果你用4XX或者别的错误状态返回结果依旧会提示跨域,所以加上always使得所有状态都可以正确返回。
Allow-Methods:请根据直接用到的请求方式进行设置,OPTIONS一定需要加上。
Allow-Headers:如果你在header的头部加上了自定义字段,请在这里也加上。

、、、
if ($request_method = 'OPTIONS') {
return 204;
}
、、、
CORS在进行POST请求前会发一次OPTIONS请求试探试探,这里我们只要检测到OPTIONS请求,我们就返回204,告诉浏览器来吧来吧。

proxy_pass       http://127.0.0.1:5000;
proxy_set_header Host $host:80;

proxy_pass就是设置Nginx转发的地址,也就是设置成Gunicorn设置的地址和端口
proxy_set_header请根据你设置Nginx Server的端口填写

最后重启一下Nginx就可以了

nginx -s relaod

大功告成

看着步骤很多,其实除了Gunicorn都不是必须的,Supervisor和Nginx你要是不想使用其实也可以不使用,我说得比较啰嗦,不过其实很容易。



作者:炸鸡翅_
链接:https://www.jianshu.com/p/192e62a5cdd2
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值