Reputation: 29
I am trying to set up a Flask server which supports both regular API calls and WebSocket connections. All traffic is routed through an NGINX load balancer, an NGINX reverse proxy and then thought uWSGI running in Emperor mode with 2 vassals - 1 for regular API and the second one for WebSockets. All connections to the first one seem to work as expected. When connecting to the second one, some connections go through, returning a 200 (both with polling and websockets), but mostly they return a 400.
NGINX reverse proxy config:
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 load balancer config
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 config:
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
I have tried setting the same "Upgrade" settings in the NGINX load balancer, but it only resulted in a 502.
NGINX error log
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 access log
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"
Upvotes: 0
Views: 538
Reputation: 705
You need gevent
event loop to be enabled directly in Your uWSGI configuration.
Add first line:
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
means that N async cores will be used (doc).
But first, you need to install it as package into your app interpreter:
pip install gevent
Note that you need uwsgi
to be installed with OpenSSL support. Else, uwsgi
will throw errors. To enable OpenSSL:
uwsgi
: pip uninstall uwsgi
sudo apt-get install libssl-dev
uwsgi
: pip install uwsgi
.If You have installed OpenSSL libs already in different location, You might find this discussion usefull.
Upvotes: 1