繁体   English   中英

致命错误 - 打开的文件太多

[英]Fatal Error - Too many open files

我尝试在我的新机器上运行 PHPUnit 测试,但出现此错误:

PHP 致命错误:消息为“RecursiveDirectoryIterator::__construct(/usr/lib/php/pear/File/Iterator)”的未捕获异常“UnexpectedValueException”:无法打开目录:/usr/lib/php/pear 中打开的文件太多/文件/迭代器/工厂.php:114

旧机器上的相同代码运行良好......

新机环境:PHP 版本:PHP 5.3.21 (cli) 旧版:PHP 5.3.14

PHPUnit output 每次:

................EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 65 / 66 ( 98%)
E

Time: 34 seconds, Memory: 438.50Mb

There were 50 errors:

1) XXXXXXXXXXX
PHP Fatal error:  Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(/usr/lib/php/pear/File/Iterator): failed to open dir: Too many open files' in /usr/lib/php/pear/File/Iterator/Factory.php:114

这可能是对运行代码的服务器的限制。 每个操作系统只允许一定数量的打开文件/句柄/套接字。 当服务器被虚拟化时,这个限制通常会进一步降低。 在 Linux 服务器上,您可以使用ulimit -n检查当前限制,如果您具有 root 访问权限,则可以使用相同的命令增加它。 我假设 Windows 服务器也有一种方法。 否则,您无能为力(除非要求您的托管商或管理员增加它)。

更多可配置限制:

/etc/security/limits.conf更改

soft nofile 1024
hard nofile 65535

通过ulimit -n 65535echo 65535 > /proc/sys/fs/file-max或在/etc/sysctl.conf增加 ulimit :

fs.file-max=65535

如何提高文件打开限制(Linux 或 Max OS):

ulimit -n 10000

解决了phpunit或/和phpdbgWarning: Uncaught ErrorException: require([..file]): failed to open stream: Too many open files in [...]

在php中,在执行之前,试试这个

exec('ulimit -S -n 2048');

不要为以后存储 DirectoryIterator 对象; 当您存储的文件超过操作系统限制(通常为 256 或 1024)时,您将收到一条错误消息,提示“打开的文件太多”。

例如,如果目录中有太多文件,这将产生错误:

<?php 
$files = array(); 
foreach (new DirectoryIterator('myDir') as $file) { 
    $files[] = $file; 
} 
?>

据推测,这种方法也是内存密集型的。

来源: http : //php.net/manual/pt_BR/directoryiterator.construct.php#87425

从睡眠模式“唤醒”我的计算机后,我遇到了这个问题。

像这样重新启动 php-fpm 修复了它。 经典关闭并重新打开解决方案。

sudo /etc/init.d/php-fpm restart

我认为这可能与我最近添加到 php 的 xdebug 有关。

我注意到当您忘记在闭包中包装某些东西时,会在 PHP 中发生这种情况。 仔细查看您最近的差异,您可能会深入了解这一点(就我而言,我在 Laravel PHP 单元工厂中引用了$faker而没有关闭。

我在 Http 池中遇到此错误,我在其中向池中添加了太多 url(大约 2000 个 url)。

我不得不将 url 分成更小的批次,错误停止了。

我认为这就是 Guzzle Pool 的工作原理,它不会在整个池完成之前关闭 curl 连接。

前任。

$responses = Http::pool(function (Pool $pool) use ($chunk) {
    return collect($chunk)->map(fn($url) => $pool->get($url));
});

变成:

collect($urls)
    ->chunk(25)
    ->each(function ($chunk) {
        $responses = Http::pool(function (Pool $pool) use ($chunk) {
            return collect($chunk)->map(fn($url) => $pool->get($url));
        });
    });

Http function 是来自 Laravel 使用 Guzzle Http 客户端的包装器 function。 https://laravel.com/docs/9.x/http-client

在服务器 debian 上你也可以去

/etc/php/php7.xx/fpm/pool.d/www.conf

rlimit_files = 10000

/etc/init.d/php7.xx restart

也许,您的文件/etc/init.d/phpx.x-fpm有一些错误。 让我们重新启动它:

sudo /etc/init.d/php7.2-fpm restart

我收到这个错误,每次 PHP 试图加载 Redis 库时,但它是由我一开始并没有真正想到的东西引起的。 当我的程序运行一段时间时,我不断收到此错误,执行重复过程。 我发现我打开了一个 cURL 会话( $ch = new curl_init(...) ),它在类的析构函数中关闭,但从未调用该析构函数。 我解决了这个问题,打开文件太多的错误消失了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM