起因flask-socket.io+gevent 突然在flask-log日志里出现大量,并且晚上高峰期直接崩了
OSError: [Errno 24] Too many open files
2026-02-26T13:49:26Z <PyWSGIServer at 0x73f3f2864350 fileno=3 address=127.0.0.1:8002> failed with OSError
估计是在线连接数超负荷了。
为什么会发生这个错误?
在 Linux/Unix 系统中,“一切皆文件”,这包括网络连接(Sockets)。由于 Flask-SocketIO 需要与客户端保持长连接(WebSocket 或长轮询),每一个连接到你服务器的客户端都会占用一个“文件描述符(File Descriptor)”。
Linux 系统默认通常会限制每个进程最多只能打开 1024 个文件描述符。当你的并发连接数(加上你的应用打开的数据库连接、日志文件、API 请求等)超过这个限制时,Gevent 在尝试接收(_accept)新的客户端连接时,就会因为无法分配新的文件描述符而直接崩溃并抛出这个错误。
系统默认限制太低:Ubuntu 默认通常是 1024,在高并发场景下瞬间就会打满。
首先查看项目gunicorn的pid
#查看项目的pid
ps aux | grep momo_api_venv

image.png
查看该进程的实时限制:
cat /proc/<PID>/limits | grep "Max open files"

image.png
查看实际占用情况
lsof -p <PID> | wc -l (查看该进程开了多少个句柄)
lsof -p <PID> (查看这些句柄具体是什么)

占用900多个了,高峰期肯定过1000了
解决
- 修改 Supervisor 配置(最关键)
由于你的 Gunicorn 是由 Supervisor 启动的,Supervisor 自身的限制决定了子进程的上限。
编辑你的 Supervisor 配置文件(通常在 /etc/supervisor/supervisord.conf )
vi /etc/supervisor/supervisord.conf
加入
[supervisord]
minfds=65535 ; 确保主进程支持高句柄数

image.png
- 修改 Systemd 服务限制
sudo EDITOR=vi systemctl edit supervisor
写入内容
[Service]
LimitNOFILE=65535
输入 :wq 保存并退出。
#重新加载生效
sudo systemctl daemon-reload
sudo systemctl restart supervisor

image.png
用前面的方法,看下最大openfiles是否修改成功

image.png