ReactJS使用serve部署发布后数分钟出现EMFILE打开文件过多报错
报错信息
Error: EMFILE: too many open files, open'C:\WEBSITES\gradient_mobinsbtraining\build\asset\images\homeImage\logoHome\image\logo-5.png' Emitted 'error' event on ReadStream instance at: at internal/fs/streams.js:136:12 at FSReqCallback.oncomplete (fs.js:156:23) { errno: -4066, code: 'EMFILE', syscall: 'open', path: 'C:\WEBSITES\gradient_mobinsbtraining\build\asset\images\homeImage\logoHome\image\logo-5.png'
报错原因
EMFILE是操作系统抛出的错误,代表当前进程打开的文件描述符数量已经超出系统允许的单进程上限。在React项目用serve部署的场景下,触发该错误的常见原因如下:
serve本身定位是轻量本地测试服务器,没有做文件句柄复用逻辑,大量静态资源请求进来时,每个请求都会单独创建文件读取流,读取完成后句柄释放不及时,运行数分钟后累计量达到阈值就会报错- Windows系统默认的单进程允许打开的文件句柄上限远低于Linux/Mac系统,高访问量场景下更容易触发该问题
- 项目内静态资源(图片、字体等)数量过多,
serve没有做静态资源缓存,每次请求对应资源都会重新打开文件,进一步加剧了文件句柄的消耗
解决方法
本地测试场景临时修复
- 调整Windows系统单进程文件句柄上限:用管理员权限打开PowerShell,执行如下命令后重启电脑生效
Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -Name TcpNumConnections -Value 16384 - 启动
serve时添加参数减少不必要的句柄占用:serve -s build --no-clipboard
生产环境推荐方案
- 不使用
serve作为生产环境静态资源服务器,替换为成熟的服务器软件:- Nginx:将build目录下的所有文件放到Nginx的静态资源托管目录,配置静态资源缓存规则,天然支持文件句柄复用和资源缓存,完全不会触发该问题
- Apache:和Nginx逻辑一致,配置静态资源托管规则即可
- 如果坚持使用Node.js生态的服务器,可以用
http-server替代serve,启动时开启静态资源缓存,减少重复文件读取的句柄消耗:
其中http-server build -c 3600-c 3600代表静态资源缓存有效期为1小时。
内容的提问来源于stack exchange,提问作者Erfuun Ghayoomi
相关产品推荐
相关产品推荐

