起因 最近想要在博客中增加 Google AdSense,安装了 WordPress 插件,打开博客管理后台时,一直加载不出来。以为开了代理的问题,关掉代理,发现依然打不开。猜想可能是安装的插件有问题,导致加载失败。登录到服务器,查看 nginx 的日志。
错误日志 在 nginx 的 error.log 发现了如下信息FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 32768 bytes)
,排除是插件导致的问题。
这个问题发生的原因是,PHP 程序已耗尽了可允许分配的最大内存 33554432 bytes,也就是 32 MB,尝试分配 32768 字节时发生了致命的错误。那就是说,我们在 php 服务的配置 memory_limit
是 32MB,这个值太小,需要修改该值。
1 2 3 4 019/11/23 14:24:50 [error] 16258#16258: *490568 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 32768 bytes) in /xxx/xxx/xxx/xyz.php on line 1684" while reading response header from upstream, client: 192.198.83.166, server: www.zhoujunwen.com, request: "POST /xmlrpc.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "blog.zhoujunwen.com" 2019/11/23 14:24:53 [error] 16258#16258: *490582 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 28672 bytes) in /xxx/xxx/xxx/xyz.php on line 115" while reading response header from upstream, client: 67.205.37.93, server: www.zhoujunwen.com, request: "POST /xmlrpc.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "blog.zhoujunwen.com" 2019/11/23 14:31:16 [error] 16258#16258: *490717 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 28672 bytes) in /xxx/xxx/xxx/xyz.php on line 115" while reading response header from upstream, client: 103.15.50.211, server: www.zhoujunwen.com, request: "POST /xmlrpc.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "blog.zhoujunwen.com" 2019/11/23 14:40:20 [error] 16258#16258: *490855 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 28672 bytes) in /xxx/xxx/xxx/xyz.php on line 115" while reading response header from upstream, client: 109.95.158.82, server: www.zhoujunwen.com, request: "POST /xmlrpc.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "blog.zhoujunwen.com"
排查 我们通过 php 命令查看系统信息:
在 console 中输出如下信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 memory_limit => 128 => 128 report_memleaks => On => On Collecting memory statistics => No mem_emalloc_count => 0 mem_emalloc_amount => 0 mem_ecalloc_count => 0 mem_ecalloc_amount => 0 mem_erealloc_count => 0 mem_erealloc_amount => 0 mem_efree_count => 0 mem_efree_amount => 0 mem_malloc_count => 0 mem_malloc_amount => 0 mem_calloc_count => 0 mem_calloc_amount => 0 mem_realloc_count => 0 mem_realloc_amount => 0 mem_free_count => 0 mem_free_amount => 0 mem_estrndup_count => 0 mem_strndup_count => 0 mem_estrdup_count => 0 mem_strdup_count => 0 mem_edupl_count => 0 mem_dupl_count => 0
看到这个结果,自动补全黑人问号,什么情况,memory_limit
的值为 128, 也就是 128MB,这个值远远大于 32MB 的。
我们在项目根目录创建一个 test.php 文件,输入内容:
1 2 3 <? php echo phpinfo();exit ; <php
在浏览器中查看:http://xxx.xxx.com/index.php
:
从页面反馈的信息可以看出,PHP的配置文件是/usr/local/php/etc/php.ini
,我们使用 vim 从服务器端打开该文件:
1 vim /usr/local /php/etc/php.ini
在vim编辑器中,在命令模式下,通过?memory_limit
搜索配置项,发现该配置项的值确实是 128,和通过 PHP 命令查看到的信息一致。这说明,PHP的配置没有问题,问题可能在 php-fpm 中,找到 php-fpm 的配置文件:/usr/local/php/etc/php-fpm.conf
,当然,如果不知道 php-fpm.conf 文件在什么地方,可以通过名find / -name php-fpm.conf
来查看确定位置。
同样通过 vim 打开 php-fpm.conf 文件,在里面查找 memory_limit 关键字,很遗憾,发现并没有这个配置项。此时是不是有点失望呢?别气馁,仔细看看 php-fpm.conf 这个文件,就会发现如下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ;;;;;;;;;;;;;;;;;;;; ; Pool Definitions ; ;;;;;;;;;;;;;;;;;;;; ; Multiple pools of child processes may be started with different listening ; ports and different management options. The name of the pool will be ; used in logs and stats. There is no limitation on the number of pools which ; FPM can handle. Your system will tell you anyway :) ; Include one or more files. If glob(3) exists, it is used to include a bunch of ; files from a glob(3) pattern. This directive can be used everywhere in the ; file. ; Relative path can also be used. They will be prefixed by: ; - the global prefix if it's been set (-p argument) ; - /usr/local/php otherwise include=/usr/local/php/etc/php-fpm.d/*.conf
那么在 /usr/local/php/etc/php-fpm.d/
目录下一次查看 后缀为 .conf
的文件,查找是否有 memory_limit
关键字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; Default Value: nothing is defined by default except the values in php.ini and ; specified at startup with the -d argument ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com php_flag[display_errors] = off php_admin_value[error_log] = /usr/local/php/var/log /www-php-errors.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 32 M ``` 我们在其中一个配置文件中发现了 `php_admin_value[memory_limit] = 32 M` 配置项,没错,这个就是 phpinfo 输出信息中显示的 32 M 的内存。我们将其改为 `128 M`,保存。 重启 php-fpm 和 nginx: ``` bash # 查看 php-fpm的进程号 ps -ef| grep php-fpm# ${PHP_FPM_PID} 就是上面上到的进程号,替换一下 kill -USR2 ${PHP_FPM_PID} # 重启 php-fpm php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf # 重启 nginx nginx -s reload