自从几天以来,我的一个Cronjobs遇到了严重的问题。有时我会收到以下错误(每小时一次或两次):
PHP致命错误:require_once():无法在[...]中打开所需的'MailError.php'(include_path ='。:: / usr / www / users / web1 / master / sys / classes:..')
PHP无法打开的文件每次都会更改。此外,所需文件肯定存在并且可读。在Cronjob处于活动状态时,我试图用lsof | grep .php
查找任何锁定的文件,但是没有锁定的* .php文件。
在我的require_once
方法中调用spl_autoload_register
:
spl_autoload_register(function($className){
$filePath = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$includePaths = explode(PATH_SEPARATOR, get_include_path());
foreach($includePaths as $includePath){
if(file_exists($includePath . DIRECTORY_SEPARATOR . $filePath)){
require_once $filePath;
return;
}
}
});
在第一次遇到问题之前,我在服务器上安装了一些新软件。 Node.js,用于进程监控的PM2,一个监听UDP套接字的Node.js脚本,以及Redis作为搜索结果缓存。我关闭了所有这些组件,现在看来Cronjob正在运行,再次没有任何错误。后来我一个接一个地打开这些组件,以检查哪个原因导致了错误,但看起来只有在打开每个组件时才会发生。
我不知道该问题的核心是什么,所以我希望我可以找到遇到相同或相似问题的人。
关于我的系统的一些有用信息:
答案 0 :(得分:0)
正如我在该线程Select() + UDP resulting in too many open files中发现的那样,该错误是由于超出了打开文件限制的结果。
在我的情况下,PHP脚本使用带有socket_create()
和socken_sendto()
的UDP套接字,并使用socket_close()
关闭它。关闭可能会失败,并且插座保持打开状态。在某个时候,打开文件的限制已被执行,PHP无法再包含任何其他文件。