转发自V2EX

Unix 套接字,本质上是一个文件( Unix/Linux 哲学:一切皆文件),Nginx 和 uwsgi 通过这个文件来进行通信。所以需要 Nginx 与 uwsgi 放在同一个机器上。

但实际上,uwsgi 本身就是一个服务器,A 服务器上的 Nginx 与 B 服务器上的 uwsgi 之间是可以通过 http 进行通信的。

要让 uwsgi 使用 http 进行通信,我们可以修改 uwsgi 的配置文件 xxx.ini:

1
2
3
4
5
6
7
8
9
[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。