部署方案
任何的部署方案都不应该脱离实际需求。Flask+uWSGI+Nginx 可以应对那些高并发、高性能的页面需求。
如果你需要:
- 轻量、可扩展的Web程序
- 易于使用的语法
- 适于高连接并发的情况
- 高性能、低占用
- 多app管理
- 高度可定制
这样的Web应用,那么Flask+uWSGI+Nginx 是你应该考虑的方案。
Flask
Flask是一个使用 Python 编写的轻量级 Web 应用框架。
uWSGI
The uWSGI project aims at developing a full stack for building hosting services.
Nginx
Nginx 是一个高性能的HTTP和 反向代理 服务器 (这里主要用于处理静态文件)。
部署环境
我们这里使用了Ubuntu 14.04 x64的VPS来部署我们的应用。
开始部署
配置virtualenv
生产环境中不同的Application往往依赖于不同的Python包。如果直接安装这些包,可能由于依赖的版本不同产生各种各样的冲突。为了避免这种情况,我们使用Virtualenv来为每个应用创建单独的虚拟环境,避免冲突。
Ubuntu的软件源中包含了virtualenv,可以直接安装:1
# apt-get install python-virtualenv
如果使用Python3:1
# apt-get install python3-virtualenv
或者使用pip安装:1
$ pip install virtualenv
创建一个virtualenv环境是非常简单的。1
$ virtualenv venv
Python环境和一些必要的工具(如pip)会被安装到当前目录的venv文件夹下。
当你想激活它时,执行1
$ . venv/bin/activate
好了,你已经切换到了venv的shell下。值得注意的是,只有Python环境是虚拟的,其他环境(如C++ Lib)仍与之前没有任何区别。
上传应用
可以通过scp命令将本地的项目上传到远程主机中:1
2
3usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 ... [[user@]host2:]file2
也可以通过git等其它方式进行部署。
使用Manager启动Server
Manager是一个flask脚本,包含在flask.ext.script中。
新建manage.py,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# Set the path
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from flask.ext.script import Manager, Server, Shell
from yourpackagename import app
manager = Manager(app)
# Turn on debugger by default and reloader
manager.add_command("runserver", Server(
use_debugger=True,
use_reloader=True,
host='0.0.0.0')
)
manager.add_command("shell", Shell())
if __name__ == "__main__":
manager.run()
这样,我们就可以通过下面的命令,更方便地运行和调试项目:1
2$ python manage.py runserver #服务器模式
$ python manage.py shell #Shell模式
安装所有需要的包
对Python而言,迁移我们的依赖是非常容易的。
pip freeze > requirements.txt将包依赖信息保存,而pip install -r requirements.txt会自动从网上下载并安装所有包。
在你Application的本地的virtualenv环境中生成requirements.txt,然后在remote的virtualenv环境中安装它们。
注意:保证对每个应用的环境是干净的。
配置uwsgi
先安装uwsgi:1
$ pip install uwsgi
在应用目录中新建config.ini,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22[uwsgi]
# uwsgi 启动时所使用的地址与端口
socket = 127.0.0.1:8001
# python 启动程序文件
wsgi-file = manage.py
# python 程序内用以启动的 application 变量名
callable = app
# 处理器数
processes = 4
# 线程数
threads = 2
# 状态检测地址
stats = 127.0.0.1:9191
# uwsgi 使用的协议
protocol=http
一些选项(如处理器数、线程数)不是必要的,更多选项可以参考uwsgi文档。
测试一下是否成功:1
$ uwsgi config.ini
配置supervisor
Supervisor是一个进程管理工具。这里使用它进行uwsgi进程的管理,以实现后台运行、自动重启。
在Ubuntu下可以直接通过下面的命令安装Supervisor:1
# apt-get install supervisor
安装好后,只需要在/etc/supervisor/conf.d/ 新建一个配置文件,就可以增加一个Supervisor进程。
例如,我们的应用目录在主目录下,名为flask-app。新建一个flask-app.conf,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[program:flask-app]
# 启动命令入口
command= /home/your-username/flask-app/venv/bin/uwsgi /home/mocimy/flask-app/config.ini
# 命令程序所在目录
directory=/home/your-username/flask-app
# 运行命令的用户名
user=your-username
# 自动启动
autostart=true
# 自动重启
autorestart=true
#日志地址
stdout_logfile=/log/uwsgi_supervisor.log
快使用supervisor启动我们的应用看看吧!1
2# service supervisor restart
# supervisorctl #进程管理
supervisorctl可以管理/etc/supervisor/conf.d 下配置好的所有进程。
start 启动进程
stop 终止进程
status 查看进程状态
配置nginx
为什么还要使用nginx?可以看这里:https://serverfault.com/questions/590819/why-do-i-need-nginx-when-i-have-uwsgi
简单来说nginx更安全、帮助我们更好地处理静态资源。1
# apt-get install nginx #安装
推荐修改/ext/nginx/sites-available/default文件,不需要改动/etc/nginx/nginx.conf
修改server配置如下:1
2
3
4
5
6
7
8
9
10
11
12server {
listen 80;
server_name localhost; #填写公网IP/域名
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8001; //和uwsgi中的设置保存一致
uwsgi_param UWSGI_PYHOME /home/your-username/flask-app/venv; # 指向虚拟环境目录
uwsgi_param UWSGI_CHDIR /home/your-username/flask-app; # 指向网站根目录
uwsgi_param UWSGI_SCRIPT manage:app; # 指定启动程序
}
}
重启nginx:1
# service nginx restart
大功告成,快打开浏览器查看一下吧!
总结
许多教程给出的解决方案由于版本不同、环境配置不同、搭建需求不同等等原因不能照搬到实际部署中。查阅官方文档、总结经验、反复调试是解决问题的最佳途径。Python的Server搭建相对PHP来说更困难,但也有着其独有的优势,值得尝试。