使用uwsgi部署Flask,不使用Unix套接字鏈接Nginx

若是你在Google或者百度或者某些技術社區上面搜索uwsgi + Flask,你會發現大量的文章,是教你如何使用uwsgi + flask + Nginx搭建網站。以下圖所示:nginx

怪現狀

並且這些文章,所有都像是約定俗成同樣,必定會首先用命令行啓動uwsgi,測試uwsgi與Flask運行是否正常,而後寫uwsgi的配置文件。而後使用Unix 套接字溝通uwsgi與Nginx。因此uwsgi的配置文件裏面必定會寫成相似於下面這樣:web

socket = /xxx/yyy/zzz.sock
複製代碼

Nginx的配置必定有相似於下面這一段:apache

location / {
        include uwsgi_params;
        uwsgi_pass unix:///xxx/yyy/zzz.sock;
    }
複製代碼

他們爲何要這樣寫?由於他們看的別的博客上就是這樣寫的!他們知其然,可是不知其因此然。flask

有什麼問題?

這種寫法自己沒有問題,甚至Flask的官方文檔裏面也是這樣寫的,以下圖所示:安全

可是他們這樣寫,有一個基本前提——就是Flask程序、uwsgi、Nginx三個東西運行在同一個服務器上。若是用Docker,那麼這三個東西甚至須要運行到一個容器裏面。bash

若是是一個小網站,服務器資源足夠,那麼這樣寫沒有問題,Unix套接字安全性高,速度也快。服務器

那麼若是你同一個服務器上有三個Docker容器,每個容器都有一個不一樣的網站,是否是每一個容器裏面都須要安裝一個Nginx?app

對於大一些的網站,Nginx須要作負載均衡,若是把Nginx和網站放在同一臺服務器上,不管是Nginx拖垮了服務器,仍是網站拖垮了服務器,都會致使很嚴重的問題。負載均衡

能不能實現,一個服務器上直接安裝Nginx,而後服務器上的三個網站分別在三個Docker容器裏面,每一個容器裏面只有Flask和uwsgi,沒有Nginx?socket

若是你的網站大一些,你在A服務器安裝Nginx,在B、C、D、E、F服務器上不安裝Nginx,只安裝uwsgi + Flask,又怎麼作?

因此進入咱們今天的主題,安裝uwsgi + Flask(或者Django),可是不安裝Nginx(Deploy Flask with uwsgi but without Nginx)

不使用Unix套接字的uwsgi

Unix套接字,本質上是一個文件(Unix/Linux哲學:一切皆文件),Nginx和uwsgi經過這個文件來進行通訊。因此須要Nginx與uwsgi放在同一個機器上。

但實際上,uwsgi自己就是一個服務器,A服務器上的Nginx與B服務器上的uwsgi之間是能夠經過http進行通訊的。

要讓uwsgi使用http進行通訊,咱們能夠修改uwsgi的配置文件xxx.ini:

[uwsgi]
module = wsgi:app
master = true
process = 5
threads = 100
gevent = 100
async = 100
http-socket = 0.0.0.0:5001
virtualenv = /Users/kingname/.local/share/virtualenvs/ActiveScoreApi-Ax_h-Y5w
複製代碼

其餘參數的意義不是本文的重點,咱們要關心的是http-socket = 0.0.0.0:5001。它的做用把網站部署在本機的5001端口,並容許外網經過http訪問。

寫了這個配置文件之後,經過如下命令來啓動uwsgi:

uwsgi --ini xxx.ini
複製代碼

而後你使用IP:5001就能夠訪問你的網站了。此時,若是你有Nginx,那麼只須要在Nginx上設置反向代理,把80端口的請求代理到5001端口便可。

同理,把uwsgi和網站放在Docker鏡像裏面,容器開放5001端口。宿主機或者其餘機器上的Nginx直接經過IP:端口 就能夠訪問容器裏面的uwsgi,再也不須要設置Unix套接字了。

另外,若是你閱讀過uwsgi的官方文檔,你還會發現,除了http-socket = 0.0.0.0:5001外,你也能夠把它改爲http = 0.0.0.0:5001。那麼這兩種寫法是否同樣呢?

在官方文檔裏面特別區分了它們的使用場景:

The http and http-socket options are entirely different beasts. The first one spawns an additional process forwarding requests to a series of workers (think about it as a form of shield, at the same level of apache or nginx), while the second one sets workers to natively speak the http protocol. TL/DR: if you plan to expose uWSGI directly to the public, use --http, if you want to proxy it behind a webserver speaking http with backends, use --http-socket.

簡言之,若是你直接把uwsgi做爲服務器,uwsgi啓動之後,直接就把IP:端口拿給別人訪問,那麼你就可使用http;若是你的uwsgi前面還擋了一個Nginx,那麼你就使用http-socket

相關文章
相關標籤/搜索