同样的 GraphQL API 请求,在浏览器中时而响应 500,且无响应数据,时而响应 200,且有响应数据
1、同样的 GraphQL API 请求,在浏览器中时而响应 500,且无响应数据,时而响应 200,且有响应数据。如图1
2、当响应 500 时,无响应数据。决定设置错误级别,以输出更为详细的错误日志。在入口文件 index.php 中,编写如下实现。如图2
1 2 3 4 | 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
1 2 3 4 5 6 | /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。确认程序中某处内存占用过大。
1 | ini_set ( 'memory_limit' , '1000M' ); |
5、编辑 /var/www/object/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php ,在 262 行附近,打印出相应数据输出至日志文件中。如图4
1 2 3 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); |
1 2 3 4 5 6 7 | /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 约束,进而将整张表的数据全部查询出来放入了内存中,进而导致内存超出限制。
近期评论