Flask部署
开发时我们是通过Flask内置得服务器进行调试,但在生成环境我们不应再使用Flask内置服务器而应该用更稳定的服务器接受客户端的请求,Flask应用处理业务。
Python应用的线上部署离不开WSGI。
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。
简单说它就是Web服务器和Web应用的中间件。
它的作用是方便Web应用的移植。因为Web应用的框架选择将限制Web服务器的选择。有了WSGI只要Web应用和Web服务器准守WSGI接口规范,就可以随意组合Web应用和Web服务器了。
现有已经有很多成熟的WSGI容器(Gunicorn,Tornado,Gevent),它提供了Web服务器并实现了WSGI接口,它们可以很方便的于Flask应用对接上。
uWSGI
uWSGI是一个Web应用服务器,它支持WSGI协议同时也支持自有的uWSGI协议。
它的目标为开发服务提供全栈的构建工具。它能作为应用服务器(支持各种编程语言:Python,perl,ruby,PHP等),代理服务器,进程管理器和监视器。这些都使用统一的API和配置风格。
在Python应用中一般将它作为应用服务器配合Nginx使用。
安装
构建uWSGI,你需要Python和一个C编译器。
1 | $ yum update |
依赖的环境安装好后,就可以通过pip
安装uwsgi
了。
1 | $ pip install uwsgi |
第一个WSGI应用
1 | def application(env, start_response): |
将其保存为 foobar.py。
foorbar.py是个符合WSGI接口规范的应用(入口函数默认是 application)。当uWSGI加载foobar.py文件时会自动去查找application函数并在必要时调用它。
1 | uwsgi --http :9090 --wsgi-file foorbar.py |
注意: 当你有一个前端web服务器(Nginx)时,不要使用--http
,使用--http-socket
。
--http
参数指定HTTP监听地址和端口,--wsgi-file
参数指定WSGI应用的程序入口。
默认情况下uWSGI启动一个单一的进程和一个单一的线程。你可以通过--processes
和--threads
开启多个进程和线程。
1 | uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 |
上面例子uWSGI启动了4个应用进程,每个进程有2个线程。并启动了一个 --master
主进程,用于监控其他进程状态,如果进程死了将它重启。通过--stats 127.0.0.1:9191
你听过浏览器访问127.0.0.1:9191
获取JSON格式的应用运行信息。
uWSGI提供了工具uwsgitop 用于监控应用运行状态,可以通过pip
安装它们。
配置文件
uWSGI支持通过配置启动服务器,这样就不需要在命令行输入一串指令。 (uWSGI配置上有上百种)
uWSGI支持多中配置文件格式:ini
,xml
,yaml
,json
。
1 | [uwsgi] |
启动服务:
1 | uwsgi myapp.ini |
uWSGI中常用的配置项有:
- chdir =/opt/myapp #指定项目目录
- socket =xxx #指定uwsgi的客户端将要连接的socket的路径(使用UNIX socket的情况)或者地址(使用网络地址的情况)
- callable = xxx #指定WSGI 加载应用那个变量调用。默认是:application
- virtualenv = /xxx/xxx #指定虚拟环境变量。其他指定字段还有:home,venv,pyhome
- uid = xxx #指定uWSGI服务器运行时的用户id
- gid = xxx #指定 uWSGI服务器运行时的用户组id
- procname-prefix-spaced = xxx #指定工作进程名称的前缀
- daemonize =%(chdir)/xxx.log # 进程在后台运行,并将日志打印到指定文件
- logfile-chmod =644 # 指定日志文件的权限
例子:
1 | [uwsgi] |
uwsgi操作命令:
1 | $ uwsgi uwsgi.ini # 启动uwsgi服务 |
Nginx配置
在配置Nginx前需要将 uWSGI配置文件http
换为socket
1 | [uwsgi] |
Nginx配置如下:
1 | location / { |
通过配置socket=/tmp/uwsgi.sock
,启动uWSGI服务器后,它会自动创建一个”/tmp/uwsgi.sock”文件。在Nginx配置中地址指定这文件。这样我们就不用写死端口。
1 | location /myapp { |
运行Flask应用
将Flask应用集成进去很简单,只需要在uWSGI配置文件callable
指向Flask启动变量。
1 | from flask import Flask |
1 | [uwsgi] |
setuptools
setuptools是python应用的打包和分发工具。通过它你可以将你的应用打包成egg包或tar.gz包。
将应用打成压缩包后你就可以方便发布和部署。
注意: 如果你的Python2 >= 2.7.9或Python3 >= 3.4从python.org安装成功的,则你已经在系统上安装了 pip 和 setuptools。
打包Flask应用
setuptools打包文件名为:setup.py。所有打包规则都写在里面。
1 | from setuptools import setup,find_packages |
MANIFEST.in 文件:
1 | recursive-include yourapplication/templates * |
安装执行文件
创建egg包
1 | python setup.py bdist_egg |
该命令将在当前目录下dist 创建一个egg文件。文件名格式是:应用-版本号-Python版本.egg
注意: python的egg 是一个包含所有包数据的文件包,类式Java的jar文件,是个工程打包文件,便于安装部署。
创建tar.gz包
1 | python setup.py sdist --formats=gztar |
创建的文件类型是tar.gz
安装应用
1 | python setup.py install |
将应用安装到当前Python环境的 site-packages目录下。这样其他应该就可以像导入标准库一样导入它。
Fabric3
Fabric是一个Python写的SSH任务管理库。它可以实现Python应用的自动打包发布部署。
Fabric3是最新的python(2.7或3.4+)版本。它和Fabric无法共存,但保存对Python2的兼容。
安装
1 | pip uninstall Fabric |
Hello world
Fabric默认会去查找目录下 fabfile.py 文件,如果你的配置文件名不是这可以通过 -f 传递给 Fabric。
1 | def hello(): |
1 | fab hello |
你也可以向放传递参数:
1 | def hello(name="world"): |
1 | fab hello:name=Fynn |
环境变量
Fabric中的env
变量是个Python字典,用于设定Fabric中配置值。常用来设置远程服务器域名和SSH账号。
- env.host
- Default:None
- 设定一个域名的字符串
- env.hosts
- Default:[]
- 设定一组域名的字符串(域名部分)
- env.password
- Default:None
- 设定SSH账户密码
- env.passwords
- Default:{}
- 设定一组远程服务器SSH账户密码。key是完整的域名(env.host_string),value是密码
- env.port
- Default: None
- 设定远程服务器端口
常用API
- local: 执行本地命令,例如:
local('ls -la')
- run: 执行远程命令,例如:
run('ls -la')
- lcd: 切换本地目录
- cd: 切换远程目录
- put:上传本地文件到远程主机
- get: 从远程主机下载文件到本地
- reboot: 重启远程主机。reboot()
- sudo: sudo执行远程命令
- @task : 函数装饰器,装饰的函数fab才能调用
- @runs_once : 函数装饰器,装饰的函数只执行一次
例子
1 | from fabric.api import * |
参考
http://docs.fabfile.org/en/1.14/index.html
https://uwsgi-docs.readthedocs.io/en/latest/index.html#
https://henulwj.github.io/2016/04/20/uwsgi-common-use-parameters/
http://yansu.org/2013/06/07/learn-python-setuptools-in-detail.html
作者: Fynn
链接: https://fynn90.github.io/2018/02/04/Flask%E9%83%A8%E7%BD%B2/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可