centosflask+uWSGI+nginx部署
1. 概念
Flask自带webserver--Werkzeug,能够搭建服务,运行网站。但在开发时,通常会用专业的--uWSGI。php
另外,常配合使的还有nginx。html
1.1. uWSGI
uWSGI是一个全站式的托管服务,它实现了应用服务器(支持多种编程语言)、代理、进程管理器、监视器。取名为uWSGI是由于它最先实现的是Python语言的WSGI。python
WSGI:一种实现python解析的通用接口标准/协议,是一种通用的接口标准或者接口协议,实现了pythonweb程序与服务器之间交互的通用性。linux
利用它,web.py或bottle或者django等等的pythonweb开发框架,就能够轻松地部署在不一样的webserver上了;nginx
uwsgi:同WSGI同样是一种通讯协议web
uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型,它与WSGI相比是两样东西。apache
uWSGI:一种pythonwebserver或称为Server/Gatewaydjango
uWSGI相似tornadoweb或者flup,是一种pythonwebserver,uWSGI是实现了uwsgi和WSGI两种协议的Web服务器,负责响应python的web请求。编程
由于apache、nginx等,它们本身都没有解析动态语言如php的功能,而是分派给其余模块来作,好比apache就能够说内置了php模块,让人感受好像apache就支持php同样。json
uWSGI实现了wsgi协议、uwsgi协议、http等协议。Nginx中HttpUwsgiModule的做用是与uWSGI服务器进行交换。
uWSGI是C语言写的,性能比较高。uWSGI包括四个部分:
1.2. Nginx
Nginx是高效的Web服务器和反向代理服务器,能够用做负载均衡(当有n个用户访问服务器时,能够实现分流,分担服务器的压力),能够进行安全过滤,防DDOS攻击等。与Apache相比,Nginx支持高并发,能够支持百万级的TCP链接,十万级别的并发链接,部署简单,内存消耗少,成本低,但Nginx的模块没有Apache丰富。
Nginx支持uWSGI的uwsgi协议,所以咱们能够将Nginx与uWSGI结合起来,Nginx经过uwsgi_pass将动态内容交给uWSGI处理。
1.3. 为何要用nginx
既然uWSGI能够起到Web服务器的做用,那么为何有了uWSGI还须要Nginx呢?
最广泛的说法是Nginx对于处理静态文件更有优点,性能更好。其实若是是小网站,没有静态文件须要处理,只用uWSGI也是能够的,但加上Nginx这一层,优点能够很具体:
对于运维来讲比较方便,若是服务器被某个IP攻击,在Nginx配置文件黑名单中添加这个IP便可,若是只用uWSGI,那么就须要在代码中修改了。
另外一方面,Nginx是身经百战的Web服务器了,在表现上uWSGI显得更专业,好比说uWSGI在早期版本里是不支持https的,能够说Nginx更安全。
Nginx的特色是可以作负载均衡和HTTP缓存,若是不止一台服务器,Nginx基本就是必选项了,经过Nginx,将资源能够分配给不一样的服务器节点,只有一台服务器,也能很好地提升性能,由于Nginx能够经过headers的ExpiresorE-Tag,gzip压缩等方式很好地处理静态资源,毕竟是C语言写的,调用的是native的函数,针对I/O作了优化,对于动态资源来讲,Nginx还能够实现缓存的功能,配合CDN优化(这是uWSGI作不到的)。Nginx支持epoll/kqueue等高效网络库,可以很好地处理高并发短链接请求,性能比uWSGI不知道高到哪里去了。
若是服务器主机上运行了PHP,Python等语言写的多个应用,都须要监听80端口,这时候Nginx就是必选项了。由于咱们须要一个转发的服务。
因此说,Nginx基本也是必选项。因此说虽然uWSGI自己就是一个web服务,这里再次引入Nginx就是为了把Nginx做为一个反向代理,这样,一些图片、js等静态资源就能够用Nginx提供服务,而其余的转发给uWSGI,这也是咱们这套部署架构的最终目的。
2. 部署
2.1. 系统环境
centos6.5
python3.6.5
nginxn 1.10.3
uwsgi 2.0.18
2.2. uWSGI
uWSGI是一个由python实现的web容器,能够兼容性比较好地发布Django,Flask等pythonweb框架的应用。由于本质上来讲uwsgi是python的一个模块,因此能够用pipinstalluwsgi直接来安装它。
安装完成以后能够在一个合适的目录创建一个uwsgi服务器的配置文件。好比我选择在项目的根目录创建了一个uwsgiconfig.ini的文件。顺便一提,除了ini格式的配置,uwsgi还支持json,xml等多种多样的配置格式。这里以ini格式为例。
2.2.1. 配置
直接使用uwsgi运行,配置文件以下:
[uwsgi]
http= 0.0.0.0:9000
chdir = /home/web_server/flask/website
wsgi-file= run.py
callable= app
processes=4
threads=2
pidfile = /home/web_server/flask/uwsgi.pid
daemonize = /home/web_server/flask/server.log
各参数说明:
由uwsgi指定了端口后无需再指定flask的运行端口,实际是给出callable变量后,由uwsgi执行run()
socket:套接字通信端口,至关于为外界留出一个uWSGI服务器的接口,负责与Nginx通讯,但注意socket是没法直接经过http请求成功访问。
pythonpath:项目目录。
callable:程序内启用的application变量名,通常而言都是app=Flask(__name__)的因此这里是app。
processes:处理器个数。
threads:线程数。
processes和threads指出了启动uwsgi服务器以后,服务器会打开几个并行的进程,每一个进程会开几条线程来等待处理请求,显然这个数字应该合理,过小会使得处理性能很差而太大则会给服务器自己带来太大负担。
stats:获取uwsgi统计信息的服务地址
daemonize:使uWSGI进程在后台运行,并将日志打到指定的日志文件或者udp服务器.
2.2.2. 启动/中止
uWSGI 经过 xxx.ini 启动后会在相同目录下生成一个 xxx.pid 的文件,里面只有一行内容是 uWSGI 的主进程的进程号。
uWSGI 启动:
uwsgi --ini xxx.ini
uwsgi 重启:
uwsgi --reload xxx.pid
uwsgi 中止:
uwsgi --stop xxx.pid
pid文件需手动指定生成
2.2.3. 问题
关闭问题
手动指定pid文件后,实际起了4个进程,但pid中只有一个pid,使用—stop关闭也仅关闭pid文件中所记录的一个进程,其他3个只能kill
批量杀死进程:
pkill uwsgi
pkill -f uwsgi -9 # 通常用不到
2.3. nginx
2.3.1. 安装
yum install nginx
查看版本
nginx version: nginx/1.10.3
2.3.2. 配置
配置文件的路径不尽相同,centos上用yum安装时,通常配置文件在/etc/nginx/nginx.conf
修改nginx.conf配置文件,但这里不直接修改,而使用另外一种方式(推荐)
默认安装的Nginx配置文件/etc/nginx/nginx.conf内尾部有以下配置
include /etc/nginx/conf.d/*.conf;
即从外部目录/etc/nginx/conf.d/文件夹下还引入了其余配置文件。
这样,不修改默认配置文件,在/etc/nginx/conf.d/目录下新增长一个webapp.conf,从而增长配置文件体系健壮性。
webapp.conf内容以下:
server {
listen 9002; //web访问端口
server_name localhost; //服务器名
charset utf-8;
access_log /var/www/webapp/access.log; //服务器接收的请求日志,logs目录若不存在须要建立,不然nginx报错
error_log /var/www/webapp/error.log; //错误日志
client_max_body_size 100M;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9000; //须要和uwsgi的配置文件里socket项的地址相同,不然没法让uwsgi接收到请求。
#uwsgi_param UWSGI_PYHOME /var/www/webapp/venv;
uwsgi_param UWSGI_CHDIR /home/web_server/flask/web_test; //项目根目录
#uwsgi_param UWSGI_SCRIPT run:app; //启动项目的主程序(在本地上运行
//这个主程序能够在flask内置的
//服务器上访问你的项目),其实能够在uwsgi中指定
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
问题:
unknown directive "listen " in
配置文件中有tab空格,用正常空格替换便可。
2.3.3. 启动/中止
启动:nginx -c /usr/local/nginx/conf/nginx.conf
中止:
关闭nginx系统方式:
(1)命令
当nginx启动后,可使用“-s”参数向nginx管理进程(即master进程)发送信号来控制nginx:nginx -s signal
其中,signal能够是如下值:
[1] stop:快速关闭
[2] quit:安全关闭
[3] reload:重载配置文件
[4] reopen:从新打开一个log文件,主要用于日志切割
quit信号,通知nginx等待worker进程处理完当前的请求后退出,此命令只能由启动nginx的linux帐户来执行。
reload信号,通知nginx从新载入配置文件nginx.conf。 除了使用reload外,nginx只会在启动时载入一次配置文件,以后对配置文件的修改不会实时对已经运行的nginx进程生效。
当运行这个命令时,master进程会尝试读取配置文件,若是配置文件没有问题(配置文件有问题怎么验证呢?请看下文):
master进程会启动新的worker进程来运行新的配置文件并处理请求,同时会通知老的worker进程再也不处理新的请求并在处理完当前任务后退出。
若是配置文件存在问题不能执行,master进程会回退老配置文件继续工做,不会致使nginx进程整个异常退出。
linux的kill命令也能够达到相同的做用,假设nginx的master进程号(pid)是123456,那么 kill -s QUIT 123456 和 kill -s HUP 123456 这两条命令和前面quit、reload的做用相同。
关闭nginx命令1:
nginx -s quit
【3】重载配置
从新加载配置文件
(1)命令
nginx -s reload
2.4. uWSGI从新配置
uwsgi独立运行与使用nginx时的配置不同
配置文件:uwsgi_nginx.ini
[uwsgi]
socket = :9000
chdir = /home/web_server/flask/website
wsgi-file= run.py
callable= app
processes=4
threads=2
pidfile = /home/web_server/flask/uwsgi.pid
daemonize = /home/web_server/flask/server.log
3. 测试结果
3.1. uWSGI
不使用nginx,直接运行uWSGI
uwsgi uwsgi_independent.ini
3.1.1. 结果展现
访问http://ip:9000/成功。
3.2. uWSGI+ nginx
先启动uwsgi,若是不写绝对路径须要在ini文件当前路径执行
[root@soft flask]# uwsgi uwsgi_nginx.ini
启动nginx
nginx -c /etc/nginx/nginx.conf
3.2.1. 结果展现
访问http://ip:9002/成功。
注意:在配置nginx时指定。
4. 附录
4.1. 经常使用命令
ps -ef |grep uwsgi
uwsgi uwsgi.ini
uwsgi --stop uwsgi.pid
kill -9