【Flask】 利用uWSGI和Nginx发布Flask应用html
默认已经准备好python环境而且已经安装好了flask python
一 安装uwsginginx
二 安装nginxweb
http://www.javashuo.com/article/p-eeysafjq-dm.htmlsql
由于Flask比较容易上手,以前也拿flask写过几个小项目,不过当时天真地觉得只要在服务器上nohup跑一个python脚本就算是成功发布了这个flask项目。实际上这还面临不少问题,好比并发性很差,不支持异步(虽然也能够在run里面加上threaded之类的参数来解决,但终究不是正途)等等。真正通用的作法应该是用某些web容器来启动项目。接下来讲明作法,整个过程主要参考了这篇文章(https://segmentfault.com/a/1190000004294634)json
我测试部署的系统是CentOS7 x86_64,环境搭建部分(包括安装python,安装flask以及flask相关依赖)的工做就跳过了。从安装uWSGI开始讲起。flask
■ uwsgi的安装和配置 segmentfault
uWSGI是一个由python实现的web容器,能够兼容性比较好地发布Django,Flask等pythonweb框架的应用。由于本质上来讲uwsgi是python的一个模块,因此能够用pip install uwsgi直接来安装它。浏览器
安装完成以后能够在一个合适的目录创建一个uwsgi服务器的配置文件。好比我选择在项目的根目录创建了一个uwsgiconfig.ini的文件。顺便一提,除了ini格式的配置,uwsgi还支持json,xml等多种多样的配置格式。这里以ini格式为例。安全
一个典型的配置文件以下:
[uwsgi] socket = 127.0.0.1:5051 pythonpath = /home/wyz/flask module = manage wsgi-file = /home/wyz/flask/manage.py callable = app processes = 4 threads = 2 daemonize = /home/wyz/flask/server.log
依次解释一下这些配置项。socket指出了一个套接字,至关于为外界留出一个uwsgi服务器的接口。须要注意的是,socket不等于http。换句话说用这个配置起来的uwsgi服务器是没法直接经过http请求成功访问的,这一点后面还会提到,是遇到的一个坑。
pythonpath指出了项目的目录,module指出了项目启动脚本的名字而紧接着的wsgi-file指出了真正的脚本的文件名。callable指出的是具体执行.run方法的那个实体的名字,通常而言都是app=Flask(__name__)的因此这里是app。processes和threads指出了启动uwsgi服务器以后,服务器会打开几个并行的进程,每一个进程会开几条线程来等待处理请求,显然这个数字应该合理,过小会使得处理性能很差而太大则会给服务器自己带来太大负担。daemonize项的出现表示把uwsgi服务器做为后台进程启动,项的值指向一个文件代表后台中的全部输出都重定向到这个日志中去。
以上这些配置项都是一些最为常见的配置项,实际上uwsgi还有不少不少配置。。除了写一个配置文件的启动方式以外,还有命令行的启动方式,这里就很少说了。请须要的本身百度。。【抱歉】
此外上面也说到此次碰到的一个坑,就是关于socket和http的差异。从概念上来讲,socket自己不是协议而是一种具体的TCP/IP实现方式,而HTTP是一种协议且基于TCP/IP。具体到这个配置这里来,若是我只配了socket = 127.0.0.1:5051的话,经过浏览器或者其余HTTP手段是没法成功访问的。而在uwsgi这边的日志里会提示请求包的长度超过了最大固定长度。另外一方面,若是配置的是http = 127.0.0.1:5051的话,那么就能够直接经过通常的http手段来访问到目标。但这会引发nginx没法正常工做。正确的作法应该是,若是有nginx在uwsgi以前做为代理的话应该配socket,而若是想让请求直接甩给uwsgi的话那么就要配http。
配置完成以后就能够键入 uwsgi 配置文件.ini来启动uwsgi,再查看日志(若是配置了daemonize的话)若是最终没有报错,ps也能看到processes指定个数的uwsgi进程在跑的话说明成功启动。若是直接把uwsgi做为留给外部的链接接口发布应用的话固然也能够,可是通常而言咱们确定还要在uwsgi前面再加上一个nginx。nginx的好处在于能够进行安全过滤,防DDOS攻击,多台机器的负载均衡等工做。
关于uwsgi服务器的中止,官方文档说能够uwsgi -HUP之类的命令操做,可是这须要找到这个uwsgi的pid,目前为止我都仍是很粗暴地killall -9 uwsgi了。。
■ nginx的安装和配置
最开始用yum install nginx装了好多此仍是报缺乏libpcre.so.0的错,网上搜了一通发现多是由于我用的是CentOS7版本的系统而yum源中仍是适用于CentOS6的包。因此不如去网上找个rpm包或者直接下个源码包来编译安装。。。
nginx经常使用命令:
nginx 启动nginx
nginx -s stop/reload 中止nginx/重载配置文件
nginx -v 查看版本
nginx -t 测试配置文件是否有语法上的错误等
安装完成后默认的nginx的配置文件位于/etc/nginx/conf.d/default.conf,我直接修改了这个文件。在修改以前能够考虑先备个份。若是须要指定配置文件开启nginx能够加入-c参数。其实nginx默认读取的文件是/etc/nginx/nginx.conf,打开这个文件看看能够看到在其http块中有些include /etc/nginx/conf.d/*.conf,因此在那里的default.conf能够直接写server块。
以前也了解过一点关于nginx的配置问题,其要义大概就是nginx的配置文件格式比较要紧,好比要有大括号,句尾有分号等等。另外以#开头的行都是注释,均可以不用管。在nginx的这个配置中咱们主要修改如下内容:
server { listen 80; //默认的web访问端口 server_name xxxxxx; //服务器名 #charset koi8-r; access_log /home/wyz/flask/logs/access.log; //服务器接收的请求日志,logs目录若不存在须要建立,不然nginx报错 error_log /home/wyz/flask/logs/error.log; //错误日志 location / { include uwsgi_params; //这里是导入的uwsgi配置 uwsgi_pass 127.0.0.1:5051; //须要和uwsgi的配置文件里socket项的地址 //相同,不然没法让uwsgi接收到请求。 uwsgi_param UWSGI_CHDIR /home/wyz/flask; //项目根目录 uwsgi_param UWSGI_SCRIPT manage:app; //启动项目的主程序(在本地上运行 //这个主程序能够在flask内置的 //服务器上访问你的项目) } }
这样配置完后,当外部有一个80端口的请求送到本机时,先让nginx开始处理。nginx进行一些处理以后转发给这里配置的uwsgi_pass地址,恰好传送给uwsgi处理。再由uwsgi来调用项目中的代码处理请求返回。再来回味一下上面那个坑,若是当时仅仅配了一个http项而没有配置socket的话,就会致使一切容器启动都顺利,可是当我把请求发送给80端口的时候迟迟不来响应,直到超时。
* 经网友提醒,这实际上是一个Nginx和uWSGI之间配置协同的一个问题。若是uWSGI直接经过HTTP方式对外提供服务,那么nginx中须要配置proxy_pass,指出HTTP服务具体套接字,从而实现请求的转发(参考zabbix安装时的nginx配置就是这样的)。而若是将uWSGI配置为socket,经过socket对外提供服务(因为socket不涉及具体的协议,外部无法直接经过uWSGI端口访问服务也更加安全一些。好比能够在nginx中配置一些URL的拒接防止sql注入之类的),那么nginx配置就应该得是uwsgi_pass来实现请求的转发。 proxy_pass配置的时候写http://,即表示是走http协议的;uwsgi_pass的时候未指出协议,表示走socket。