一、组件介绍
1、Gunicorn
Gunicorn介绍之前,我们来看一个经典的Nginx+Gunicorn+Flask请求流程图。
大致流程:用户发起request,静态文件直接经过Nginx处理,无需过后端Server,动态请求转入Gunicorn处理,最后达到Web Server(Flask)和Web application。
为什么会出现Gunicorn?需要从WSGI说起。
WSGI全称Web Server Gateway Interface,它是一种规范,用来描述web server如何与web application通信的规范。
要实现WSGI协议,必须同时实现web server和web application,uWSGI和gunicorn都是实现了WSGI server协议的服务器,Django/Flask是实现了WSGI application协议的web框架,因此uWSGI 接收了http请求后转化为WSGI协议,uWSGI便能和Django/Flask进行通信。
WSGI协议的server: 是把HTTP协议转化成支持的网络协议。比如把HTTP协议转化成WSGI协议,让Python可以直接使用。有了通用的WSGI协议,Web开发者就能够任意选择适合自己的组合,而Web服务器和Web框架的开发者们也能够把精力集中到各自的领域。
常见的WSGI容器:主流的选择是Gunicorn和uWSGI。
1、Gunicorn
Gunicorn易于配置,兼容性好,CPU消耗很少,在豆瓣使用广泛。它支持多种Worker模式,推荐的模式有如如下几种:
同步Worker:默认模式,也就是一次只处理一个请求
异步Worker:通过Eventlet、Gevent实现的异步模式
异步IO Worker:目前支持gthread和gaiohttp两种类型
2、uWSGI
uWSGI是使用C编写的,显示了自有的uwsgi协议的Web服务器。它自带丰富的组件,其中核心组件包含进程管理、监控、IPC等功能,实现应用服务器接口的请求插件支持多种语言和平台,比如WSGI、Rack、Lua WSAPI,网管组件实现了负载均衡、代理和理由功能。
平时我们启动Django项目,通过自带的runserver (python manage.py runserver 0.0.0.0:8000)命令启动后就可以访问项目了。
因为djaong或者flask自带了一个实现了WSGI协议的server 和 application, 各个web framework也基本上都有自己实现的WSGI server, 但这个server基本上只能用来调试,不能用于生产环境,性能没保障。
一般并发量不是特别高的情况下,使用gunicorn或者uWSGI部署项目就足够了。
2、Nginx
为什么要Nginx?
Nginx也是一种web服务器,但功能和gunicorn/uWSGI有些差别。
1、Nginx没有实现WSGI协议。如果是Nginx+flask的组合的话就必须使用框架自带的WSGI server,性能相对来说比较差。
2、静态文件支持。经过配置之后,Nginx可以直接处理静态文件请求而不用经过应用服务器,避免占用宝贵的运算资源;还能缓存静态资源,使访问静态资源的速度提高。
3、并发能力。可以吸收一些瞬时的高并发请求,让Nginx先保持住连接(缓存http请求),然后后端慢慢消化。如果让Gunicorn直接提供服务,浏览器发起一个请求,鉴于浏览器和网络情况都是未知的,http请求的发起过程可能比较慢,而Gunicorn只能等待请求发起完成后,才去真正处理请求,处理完成后,等客户端完全接收请求后,才继续下一个。
4、通过Nginx的HTTP 请求缓存头处理得也比 gunicorn和uWSGI 完善。
5、多台服务器时,可以提供负载均衡和反向代理。
3、Supervisor
Supervisor是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便的监听、启动、停止、重启一个或多个进程。用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。
我们使用supervisor来确保gunicorn稳定运行在后台。
已经了解了架构和各个组件,那么下面就进行项目部署。二、程序部署和配置
项目大致情况:后端使用Django编写的restfullAPI,前端使用Vue。
1、安装环境
a、virtualenv
mkdir virtualenvs pip install virtualenv virtualenv fshare
启动virtual环境
[root@virtul-test-xq virtualenvs]# source fshare/bin/activate (fshare) [root@virtul-test-xq virtualenvs]#
b、安装nginx
cat /etc/yum.repos.d/nginx.repo
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=0 enabled=1
安装Nginx
yum install nginx -y
c、安装gunicron
pip install gunicorn
d、安装supervisor
pip install supervisor
2、部署后端
安装后端环境
pip install -r requirements.txt
3、编译前端
vue前端编译
npm run build
将编译好的build文件放置于nginx中配置的static路径。
4、配置启动程序
a、配置nginx
cat /etc/nginx/conf.d/fshare.conf
upstream fshare_server { server unix:/tmp/fshare.sock fail_timeout=0; } server { listen 80; server_name dev.fshare.test.com; access_log /var/log/nginx/fshare.test.com@test.access.log; error_log /var/log/nginx/fshare.test.com@test.error.log; client_max_body_size 2G; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; proxy_pass http://fshare_server; } location /static/ { root /datapool/fshare/; } }
启动nginx。
b、配置supervisor
cat /etc/supervisord.conf
[supervisord] logfile = /tmp/supervisord.log logfile_maxbytes = 50MB logfile_backups=10 loglevel = info pidfile = /tmp/supervisord.pid nodaemon = false minfds = 1024 minprocs = 200 umask = 022 identifier = supervisor directory = /tmp nocleanup = true childlogdir = /tmp strip_ansi = false [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [unix_http_server] file = /var/run/supervisor.sock [supervisorctl] serverurl=unix:///var/run/supervisor.sock [inet_http_server] port=127.0.0.1:9001 [program:fshare] command=/datapool/virtualenvs/fshare/bin/python /datapool/virtualenvs/fshare/bin/gunicorn wsgi -b unix:/tmp/fshare.sock -w 4 --pid=/tmp/fshare.pid --preload directory=/datapool/fshare/ autostart=true autorestart=true redirect_stderr=true
注意:文件名必须是supervisord.conf,不然后面启动时会有问题,因为supervisord程序启动时,会从/etc/和~/找名称为supervisord.conf的文件,如果找不到,则会启动不起来或出错。
c、将vue前端编译好的文件,放置在Nginx中配置的static文件位置
三、启动程序
经过以上配置后,我们通过supervisor就可以控制程序了。
(fshare) [root@virtul-test-xq fshare]# supervisorctl status fshare fshare RUNNING pid 46098, uptime 5:17:37
查看启动进程:
ps xau|grep fshare root 784 0.0 0.0 103252 836 pts/0 S+ 16:55 0:00 grep fshare root 46098 0.0 0.1 254960 35616 ? S 11:37 0:01 /datapool/virtualenvs/fshare/bin/python /datapool/virtualenvs/fshare/bin/gunicorn wsgi -b unix:/tmp/fshare.sock -w 4 --pid=/tmp/fshare.pid --preload root 46103 0.0 0.3 330704 103028 ? S 11:37 0:03 /datapool/virtualenvs/fshare/bin/python /datapool/virtualenvs/fshare/bin/gunicorn wsgi -b unix:/tmp/fshare.sock -w 4 --pid=/tmp/fshare.pid --preload root 46104 0.0 0.2 305732 77996 ? S 11:37 0:02 /datapool/virtualenvs/fshare/bin/python /datapool/virtualenvs/fshare/bin/gunicorn wsgi -b unix:/tmp/fshare.sock -w 4 --pid=/tmp/fshare.pid --preload root 46105 0.0 0.2 298628 70772 ? S 11:37 0:01 /datapool/virtualenvs/fshare/bin/python /datapool/virtualenvs/fshare/bin/gunicorn wsgi -b unix:/tmp/fshare.sock -w 4 --pid=/tmp/fshare.pid --preload root 46106 0.0 0.2 296120 68552 ? S 11:37 0:01 /datapool/virtualenvs/fshare/bin/python /datapool/virtualenvs/fshare/bin/gunicorn wsgi -b unix:/tmp/fshare.sock -w 4 --pid=/tmp/fshare.pid --preload
访问前端页面