同样的 GraphQL API 请求,在浏览器中时而响应 500,且无响应数据,时而响应 200,且有响应数据
1、同样的 GraphQL API 请求,在浏览器中时而响应 500,且无响应数据,时而响应 200,且有响应数据。如图1
2、当响应 500 时,无响应数据。决定设置错误级别,以输出更为详细的错误日志。在入口文件 index.php 中,编写如下实现。如图2
ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); ini_set('error_log', '/tmp/php_errors.log');
3、当响应 500 后,查看文件 /tmp/php_errors.log。PHP Fatal error: Allowed memory size of 134217728 bytes exhausted 。内容如下。如图3
/var/www # cd /tmp /tmp # ls php_errors.log /tmp # cat php_errors.log [19-Apr-2023 17:12:22 Asia/Shanghai] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 12288 bytes) in /var/www/object/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php on line 262 [19-Apr-2023 17:12:22 Asia/Shanghai] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65536 bytes) in /var/www/object/vendor/composer/ClassLoader.php on line 571
4、在入口文件 index.php 中,调整内存大小限制为 1000M ,一直响应 200。确认程序中某处内存占用过大。
ini_set('memory_limit', '1000M');
5、编辑 /var/www/object/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php ,在 262 行附近,打印出相应数据输出至日志文件中。如图4
file_put_contents(storage_path() . '/logs/doFetchAll-slice.txt', print_r($slice, true), FILE_APPEND | LOCK_EX); file_put_contents(storage_path() . '/logs/doFetchAll-queryString.txt', print_r($this->queryString, true), FILE_APPEND | LOCK_EX); $data = parent::fetchAll(...$slice); file_put_contents(storage_path() . '/logs/doFetchAll-data.txt', print_r($data, true), FILE_APPEND | LOCK_EX);
/var/www/object/storage/logs # ls -l total 65604 -rw-r--r-- 1 www www 65711812 Apr 20 01:43 doFetchAll-data.txt -rw-r--r-- 1 www www 50958 Apr 20 01:43 doFetchAll-queryString.txt -rw-r--r-- 1 www www 4820 Apr 20 01:43 doFetchAll-slice.txt -rw-r--r-- 1 www www 4530 Apr 20 01:43 explicabo78.log /var/www/object/storage/logs #
6、基于日志文件分析得出原因,在执行 SQL 查询时,未添加 limit 约束,进而将整张表的数据全部查询出来放入了内存中,进而导致内存超出限制。
近期评论