若是你在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套接字,本质上是一个文件(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
。