一、組件介紹
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
訪問前端頁面