Raku项目precomp编译报错原因及修复方法
报错触发原因
核心是操作系统进程文件句柄数限制不足,叠加Raku预编译机制的句柄占用问题触发:
- 报错信息里的
Too many open files是操作系统抛出的原生错误:单个进程打开的文件、目录、网络套接字等句柄总数超过当前配置的上限时,就会返回这个错误。 - Raku启动加载模块时会批量读取预编译目录下的缓存文件,中等规模项目依赖模块较多时,短时间内会打开大量预编译文件,很容易触及系统默认的较低句柄上限(多数Linux发行版默认仅1024)。
- 文件打开失败后会返回
Failure对象,后续编译逻辑期望拿到合法的IO::Handle对象,就会触发后续的类型检查报错,属于句柄打开失败后的级联错误。 - 删除项目本地
.precomp目录只能暂时清除已经损坏的预编译缓存,第一次启动重建缓存时依然会因为句柄数不足导致新生成的缓存文件损坏,下一次启动就会复现问题,无法从根源解决。
彻底修复方案
按以下步骤操作即可完全解决问题:
- 调高系统文件句柄上限
先执行临时命令验证效果:ulimit -n 65535,执行后启动项目,如果报错消失就可以做永久配置:- 编辑系统限制配置文件
/etc/security/limits.conf,添加如下两行配置,对所有用户生效:
* soft nofile 65535 * hard nofile 65535- 如果项目是通过systemd服务托管启动,需要在对应的service配置文件中添加
LimitNOFILE=65535,执行systemctl daemon-reload重载配置后生效。
- 编辑系统限制配置文件
- 清理全量损坏的预编译缓存
调整完句柄限制后,执行命令清理全局和项目本地的损坏缓存:rm -rf ~/.raku/precomp/* rm -rf /home/patrickb/repos/RakudoCIBot/.precomp/ - 升级Rakudo到最新稳定版本
2023年之前的Rakudo版本存在预编译加载过程中未及时释放无用文件句柄的泄漏问题,升级到最新稳定版可以减少不必要的句柄占用,避免后续句柄数再次冲高。
内容的提问来源于stack exchange,提问作者Patrick Böker
相关产品推荐
相关产品推荐

