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()"