尝试通过 NGINX 和 uWSGI 连接到 WebSocket Flask 服务器时出现 400 响应代码
400 response code when trying to connect to WebSocket Flask server through NGINX and uWSGI
我正在尝试设置一个支持常规 API 调用和 WebSocket 连接的 Flask 服务器。所有流量都通过一个 NGINX 负载均衡器、一个 NGINX 反向代理进行路由,然后在 Emperor 模式下使用 uWSGI 运行 和 2 个 vassal - 1 个用于常规 API,第二个用于 WebSockets。与第一个连接的所有连接似乎都按预期工作。当连接到第二个时,一些连接会通过,returning a 200(轮询和 websockets),但大多数情况下 return a 400。
NGINX 反向代理配置:
upstream ws_server {
server unix:/home/app_ws.sock fail_timeout=0;
}
location /socket.io {
include uwsgi_params;
uwsgi_read_timeout 60s;
uwsgi_send_timeout 60s;
uwsgi_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
uwsgi_ignore_client_abort on;
uwsgi_pass ws_server;
}
NGINX 负载均衡器配置
server {
listen 80;
server_name *********;
real_ip_header X-Forwarded-For;
set_real_ip_from 10.1.1.0/24;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_busy_buffers_size 128k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 128k;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
location / {
proxy_pass http://u2me-python-dev;
}
uWSGI vassal 配置:
callable = app
need-app = true
chdir = /home/site/
chmod-socket = 666
cpu-affinity = 1
die-on-term = true
disable-logging = true
enable-threads = true
home = /home/.environments/site
lazy-apps = true
listen = 1024
master = true
pidfile = /home/app_ws_uwsgi
processes = 1
http-websockets = true
procname = u2me.andromeda-ws
socket =/home/app_ws.sock
threads = 1
worker-reload-mercy = 30
wsgi-file = wsgi.py
我已经尝试在 NGINX 负载平衡器中设置相同的 "Upgrade" 设置,但它只会导致 502。
NGINX 错误日志
2019/08/01 15:33:59 [error] 484#0: *610 upstream prematurely closed connection while reading response header from upstream, client: 46.76.103.213, server: *********, request: "GET /socket.io/?EIO=3&transport=polling&t=MnDOnSk HTTP/1.1", upstream: "uwsgi://unix:/home/app_ws.sock:", host: "*********", referrer: "*********"
NGINX 访问日志
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "POST /socket.io/?EIO=3&transport=polling&t=MnDadM4&sid=112de3f4170f4db9ad55308b2ca1778d HTTP/1.1" 400 21 "*********" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "GET /socket.io/?EIO=3&transport=websocket&sid=112de3f4170f4db9ad55308b2ca1778d HTTP/1.1" 400 21 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "GET /socket.io/?EIO=3&transport=polling&t=MnDafi3 HTTP/1.1" 200 130 "*********" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "GET /socket.io/?EIO=3&transport=polling&t=MnDaklK HTTP/1.1" 200 130 "*********" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
您需要 gevent
事件循环直接在您的 uWSGI 配置中启用。
添加第一行:
gevent = 100
callable = app
need-app = true
chdir = /home/site/
chmod-socket = 666
cpu-affinity = 1
die-on-term = true
disable-logging = true
enable-threads = true
home = /home/.environments/site
lazy-apps = true
listen = 1024
master = true
pidfile = /home/app_ws_uwsgi
processes = 1
http-websockets = true
procname = u2me.andromeda-ws
socket =/home/app_ws.sock
threads = 1
worker-reload-mercy = 30
wsgi-file = wsgi.py
gevent=N
表示将使用N个异步核心(doc)。
但首先,您需要将它作为包安装到您的应用程序解释器中:
pip install gevent
请注意,您需要 uwsgi
安装 OpenSSL 支持。否则,uwsgi
会抛出错误。要启用 OpenSSL:
- 卸载
uwsgi
:pip uninstall uwsgi
- 安装 OpenSSL 开发库,例如Ubuntu:
sudo apt-get install libssl-dev
- 安装
uwsgi
:pip install uwsgi
.
如果您已经在不同位置安装了 OpenSSL 库,您可能会发现 this discussion 很有用。
我正在尝试设置一个支持常规 API 调用和 WebSocket 连接的 Flask 服务器。所有流量都通过一个 NGINX 负载均衡器、一个 NGINX 反向代理进行路由,然后在 Emperor 模式下使用 uWSGI 运行 和 2 个 vassal - 1 个用于常规 API,第二个用于 WebSockets。与第一个连接的所有连接似乎都按预期工作。当连接到第二个时,一些连接会通过,returning a 200(轮询和 websockets),但大多数情况下 return a 400。
NGINX 反向代理配置:
upstream ws_server {
server unix:/home/app_ws.sock fail_timeout=0;
}
location /socket.io {
include uwsgi_params;
uwsgi_read_timeout 60s;
uwsgi_send_timeout 60s;
uwsgi_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
uwsgi_ignore_client_abort on;
uwsgi_pass ws_server;
}
NGINX 负载均衡器配置
server {
listen 80;
server_name *********;
real_ip_header X-Forwarded-For;
set_real_ip_from 10.1.1.0/24;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_busy_buffers_size 128k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 128k;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
location / {
proxy_pass http://u2me-python-dev;
}
uWSGI vassal 配置:
callable = app
need-app = true
chdir = /home/site/
chmod-socket = 666
cpu-affinity = 1
die-on-term = true
disable-logging = true
enable-threads = true
home = /home/.environments/site
lazy-apps = true
listen = 1024
master = true
pidfile = /home/app_ws_uwsgi
processes = 1
http-websockets = true
procname = u2me.andromeda-ws
socket =/home/app_ws.sock
threads = 1
worker-reload-mercy = 30
wsgi-file = wsgi.py
我已经尝试在 NGINX 负载平衡器中设置相同的 "Upgrade" 设置,但它只会导致 502。
NGINX 错误日志
2019/08/01 15:33:59 [error] 484#0: *610 upstream prematurely closed connection while reading response header from upstream, client: 46.76.103.213, server: *********, request: "GET /socket.io/?EIO=3&transport=polling&t=MnDOnSk HTTP/1.1", upstream: "uwsgi://unix:/home/app_ws.sock:", host: "*********", referrer: "*********"
NGINX 访问日志
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "POST /socket.io/?EIO=3&transport=polling&t=MnDadM4&sid=112de3f4170f4db9ad55308b2ca1778d HTTP/1.1" 400 21 "*********" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "GET /socket.io/?EIO=3&transport=websocket&sid=112de3f4170f4db9ad55308b2ca1778d HTTP/1.1" 400 21 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "GET /socket.io/?EIO=3&transport=polling&t=MnDafi3 HTTP/1.1" 200 130 "*********" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
46.76.103.213 - - [01/Aug/2019:16:26:29 +0200] "GET /socket.io/?EIO=3&transport=polling&t=MnDaklK HTTP/1.1" 200 130 "*********" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
您需要 gevent
事件循环直接在您的 uWSGI 配置中启用。
添加第一行:
gevent = 100
callable = app
need-app = true
chdir = /home/site/
chmod-socket = 666
cpu-affinity = 1
die-on-term = true
disable-logging = true
enable-threads = true
home = /home/.environments/site
lazy-apps = true
listen = 1024
master = true
pidfile = /home/app_ws_uwsgi
processes = 1
http-websockets = true
procname = u2me.andromeda-ws
socket =/home/app_ws.sock
threads = 1
worker-reload-mercy = 30
wsgi-file = wsgi.py
gevent=N
表示将使用N个异步核心(doc)。
但首先,您需要将它作为包安装到您的应用程序解释器中:
pip install gevent
请注意,您需要 uwsgi
安装 OpenSSL 支持。否则,uwsgi
会抛出错误。要启用 OpenSSL:
- 卸载
uwsgi
:pip uninstall uwsgi
- 安装 OpenSSL 开发库,例如Ubuntu:
sudo apt-get install libssl-dev
- 安装
uwsgi
:pip install uwsgi
.
如果您已经在不同位置安装了 OpenSSL 库,您可能会发现 this discussion 很有用。