flask socket.io 生产环境部署

更新日期: 2024-02-07 阅读次数: 110 字数: 442 分类: Python

eventlet

由于 WSGI 不支持 WebSocket,所以需要引入 eventlet 来支持 WebSocket 协议。 (虽然 socket.io 也支持 http 协议,但是体验上会差很多。)

eventlet is the best performant option, with support for long-polling and WebSocket transports

而在开发环境,如果没有安装 eventlet,默认使用的是 Werkzeug web server:

In production mode the eventlet web server is used if available, else the gevent web server is used. If eventlet and gevent are not installed, the Werkzeug development web server is used.

安装 eventlet

ModuleNotFoundError: No module named 'eventlet'

pip install eventlet

Successfully installed dnspython-2.5.0 eventlet-0.35.1

gunicorn

将 gunicorn 启动命令参数替换为:

gunicorn --worker-class eventlet -w 1 module:app

原参数类似:

gunicorn main:app -w 3 -b 0.0.0.0:8000

gunicorn -b 参数用于指定 Gunicorn(Green Unicorn)服务器绑定的 IP 地址和端口。

所以正式环境的命令需要修改为:

gunicorn --worker-class eventlet -w 1 module:app -b 0.0.0.0:8000

如果 app 定义在 main.py 内,需要将 module 修改为 main.

否则会报错:

ModuleNotFoundError: No module named 'module'

只有一个 worker 的原因

Due to the limited load balancing algorithm used by gunicorn, it is not possible to use more than one worker process when using this web server. For that reason, all the examples above include the -w 1 option. The workaround to use multiple worker processes with gunicorn is to launch several single-worker instances and put them behind a more capable load balancer such as nginx.

使用一个 worker 也省去了使用 redis 作为多个进程间的消息队列。

github issue: https://github.com/miguelgrinberg/Flask-SocketIO/discussions/1816

也提到了:

The -w 1 is the correct one, -w 3 is not a supported setting.

自定义 socket.io 路径

如果不想使用默认的路径 /socket.io,参考:

flask socket.io 使用自定义 path 路径

nginx

http 请求与 socket.io 请求区分处理

server {
    listen 80;
    server_name _;

    location / {
        include proxy_params;
        proxy_pass http://127.0.0.1:5000;
    }

    location /static/ {
        alias <path-to-your-application>/static/;
        expires 30d;
    }

    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;
    }
}

参考

https://flask-socketio.readthedocs.io/en/latest/deployment.html

tags: socket.io flask

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式