今天在阿贝云申请了个免费的服务器,感觉还不错,有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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。