AWS EC2 上的 Flask-SocketIO 502 错误,工作人员超时 [CRITICAL]
Flask-SocketIO 502 Error on AWS EC2 with [CRITICAL] Worker Timeouts
我正在按照 this guide 在 AWS 上设置一个 Flask 应用程序的反向代理 NGINX EC2 部署。更具体地说,我正在使用代理传递给 gunicorn 服务器(请参阅下面的配置信息)。
事情已经 运行 顺利,设置的烧瓶部分工作得很好。唯一的问题是,当尝试访问依赖于 Flask-SocketIO 的页面时,客户端会抛出 502(Bad Gateway)和一些 400(Bad Request)错误。这发生在与服务器成功交谈后,但随后下一条消息(例如 https://example.com/socket.io/?EIO=3&transport=polling&t=1565901966787-3&sid=c4109ab0c4c74981b3fc0e3785fb6558)处于待处理状态,并且在 30 秒后 gunicorn worker 抛出 [CRITICAL] WORKER TIMEOUT 错误并且重新启动。
一个可能很重要的细节:我正在使用 eventlet,并且应用了猴子修补。
我试过更改端口,使用 0.0.0.0 而不是 127.0.0.1,以及其他一些小改动。我无法在网上找到任何处理这些确切问题的资源。
服务器要求的任务很轻,所以我真的不知道为什么会这样挂。
GNIX 配置:
server {
# listen on port 80 (http)
listen 80;
server_name _;
location ~ /.well-known {
root /home/ubuntu/letsencrypt;
}
location / {
# redirect any requests to the same URL but on https
return 301 https://$host$request_uri;
}
}
server {
# listen on port 443 (https)
listen 443 ssl;
server_name _;
...
location / {
# forward application requests to the gunicorn server
proxy_pass http://127.0.0.1:5000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /socket.io {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:5000/socket.io;
}
...
}
启动 gunicorn 服务器:
gunicorn -b 127.0.0.1:5000 -w 1 "app:create_app()"
客户端套接字声明:
var protocol = window.location.protocol
var socket = io.connect(protocol + '//' + document.domain + ':' + location.port);
Requirements.txt:
Flask_SQLAlchemy==2.4.0
SQLAlchemy==1.3.4
Flask_Login==0.4.1
Flask_SocketIO==4.1.0
eventlet==0.25.0
Flask==1.0.3
Flask_Migrate==2.5.2
客户端错误消息示例:
POST https://example.com/socket.io/?EIO=3&transport=polling&t=1565902131372-4&sid=17c5c83a59e04ee58fe893cd598f6df1 400 (BAD REQUEST)
socket.io.min.js:1 GET https://example.com/socket.io/?EIO=3&transport=polling&t=1565902131270-3&sid=17c5c83a59e04ee58fe893cd598f6df1 400 (BAD REQUEST)
socket.io.min.js:1 GET https://example.com/socket.io/?EIO=3&transport=polling&t=1565902165300-7&sid=4d64d2cfc94f43b1bf6d47ea53f9d7bd 502 (Bad Gateway)
socket.io.min.js:2 WebSocket connection to 'wss://example.com/socket.io/?EIO=3&transport=websocket&sid=4d64d2cfc94f43b1bf6d47ea53f9d7bd' failed: WebSocket is closed before the connection is established
示例 gunicorn 错误消息(注意:第一行是打印语句的结果)
Client has joined his/her room successfully
[2019-08-15 20:54:18 +0000] [7195] [CRITICAL] WORKER TIMEOUT (pid:7298)
[2019-08-15 20:54:18 +0000] [7298] [INFO] Worker exiting (pid: 7298)
[2019-08-15 20:54:19 +0000] [7300] [INFO] Booting worker with pid: 7300
您需要将 eventlet
worker 与 Gunicorn 一起使用:
gunicorn -b 127.0.0.1:5000 -w 1 -k eventlet "app:create_app()"
我正在按照 this guide 在 AWS 上设置一个 Flask 应用程序的反向代理 NGINX EC2 部署。更具体地说,我正在使用代理传递给 gunicorn 服务器(请参阅下面的配置信息)。
事情已经 运行 顺利,设置的烧瓶部分工作得很好。唯一的问题是,当尝试访问依赖于 Flask-SocketIO 的页面时,客户端会抛出 502(Bad Gateway)和一些 400(Bad Request)错误。这发生在与服务器成功交谈后,但随后下一条消息(例如 https://example.com/socket.io/?EIO=3&transport=polling&t=1565901966787-3&sid=c4109ab0c4c74981b3fc0e3785fb6558)处于待处理状态,并且在 30 秒后 gunicorn worker 抛出 [CRITICAL] WORKER TIMEOUT 错误并且重新启动。
一个可能很重要的细节:我正在使用 eventlet,并且应用了猴子修补。
我试过更改端口,使用 0.0.0.0 而不是 127.0.0.1,以及其他一些小改动。我无法在网上找到任何处理这些确切问题的资源。
服务器要求的任务很轻,所以我真的不知道为什么会这样挂。
GNIX 配置:
server {
# listen on port 80 (http)
listen 80;
server_name _;
location ~ /.well-known {
root /home/ubuntu/letsencrypt;
}
location / {
# redirect any requests to the same URL but on https
return 301 https://$host$request_uri;
}
}
server {
# listen on port 443 (https)
listen 443 ssl;
server_name _;
...
location / {
# forward application requests to the gunicorn server
proxy_pass http://127.0.0.1:5000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /socket.io {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:5000/socket.io;
}
...
}
启动 gunicorn 服务器: gunicorn -b 127.0.0.1:5000 -w 1 "app:create_app()"
客户端套接字声明:
var protocol = window.location.protocol
var socket = io.connect(protocol + '//' + document.domain + ':' + location.port);
Requirements.txt:
Flask_SQLAlchemy==2.4.0
SQLAlchemy==1.3.4
Flask_Login==0.4.1
Flask_SocketIO==4.1.0
eventlet==0.25.0
Flask==1.0.3
Flask_Migrate==2.5.2
客户端错误消息示例:
POST https://example.com/socket.io/?EIO=3&transport=polling&t=1565902131372-4&sid=17c5c83a59e04ee58fe893cd598f6df1 400 (BAD REQUEST)
socket.io.min.js:1 GET https://example.com/socket.io/?EIO=3&transport=polling&t=1565902131270-3&sid=17c5c83a59e04ee58fe893cd598f6df1 400 (BAD REQUEST)
socket.io.min.js:1 GET https://example.com/socket.io/?EIO=3&transport=polling&t=1565902165300-7&sid=4d64d2cfc94f43b1bf6d47ea53f9d7bd 502 (Bad Gateway)
socket.io.min.js:2 WebSocket connection to 'wss://example.com/socket.io/?EIO=3&transport=websocket&sid=4d64d2cfc94f43b1bf6d47ea53f9d7bd' failed: WebSocket is closed before the connection is established
示例 gunicorn 错误消息(注意:第一行是打印语句的结果)
Client has joined his/her room successfully
[2019-08-15 20:54:18 +0000] [7195] [CRITICAL] WORKER TIMEOUT (pid:7298)
[2019-08-15 20:54:18 +0000] [7298] [INFO] Worker exiting (pid: 7298)
[2019-08-15 20:54:19 +0000] [7300] [INFO] Booting worker with pid: 7300
您需要将 eventlet
worker 与 Gunicorn 一起使用:
gunicorn -b 127.0.0.1:5000 -w 1 -k eventlet "app:create_app()"