我们的应用程序运行在AWS的Docker容器中:
- 操作系统:Ubuntu 14.04.2 LTS (trusted Tahr) Nginx版本:Nginx/1.4.6 (Ubuntu)Memcached版本:Memcached 1.4.14
- PHP版本:PHP 5.5.9-1ubuntu4.11 (cli) (build: Jul 2 2015 15:23:08)
- 系统内存:7.5 GB
我们得到空白页和404错误频率较低。在检查日志时,我发现php-child进程被杀死,内存似乎主要由memcache和php-fpm进程使用,并且空闲内存非常少。
memcache配置为使用2gb内存
这里是php www.conf
pm = dynamic
pm.max_children = 30
pm.start_servers = 9
pm.min_spare_servers = 4
pm.max_spare_servers = 14
rlimit_files = 131072
rlimit_core = unlimited
错误日志
/var/log/nginx/php5-fpm.log
[29-Jul-2015 14:37:09] WARNING: [pool www] child 259 exited on signal 11 (SIGSEGV - core dumped) after 1339.412219 seconds from start
/var/log/nginx/error.log
2015/07/29 14:37:09 [error] 141#0: *2810 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: x.x.x.x, server: _, request: "GET /suggestions/business?q=Selectfrom HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "example.com", referrer: "http://example.com/"
/var/log/nginx/php5-fpm.log
[29-Jul-2015 14:37:09] NOTICE: [pool www] child 375 started
/var/log/nginx/php5-fpm.log:[29-Jul-2015 14:37:56] WARNING: [pool www] child 290 exited on signal 11 (SIGSEGV - core dumped) after 1078.606356 seconds from start
Coredump
Core was generated by php-fpm: pool www.Program terminated with signal SIGSEGV, Segmentation fault.#0 0x00007f41ccaea13a in memcached_io_readline(memcached_server_st*, char*, unsigned long, unsigned long&) () from /usr/lib/x86_64-linux-gnu/libmemcached.so.10
dmesg
[Wed Jul 29 14:26:15 2015] php5-fpm[12193]: segfault at 7f41c9e8e2da ip 00007f41ccaea13a sp 00007ffcc5730ce0 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
[Wed Jul 29 14:28:26 2015] php5-fpm[12211]: segfault at 7f41c966b2da ip 00007f41ccaea13a sp 00007ffcc5730ce0 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
[Wed Jul 29 14:29:16 2015] php5-fpm[12371]: segfault at 7f41c9e972da ip 00007f41ccaea13a sp 00007ffcc5730b70 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
[Wed Jul 29 14:35:36 2015] php5-fpm[12469]: segfault at 7f41c96961e9 ip 00007f41ccaea13a sp 00007ffcc5730ce0 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
[Wed Jul 29 14:35:43 2015] php5-fpm[12142]: segfault at 7f41c9e6c2bd ip 00007f41ccaea13a sp 00007ffcc5730b70 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
[Wed Jul 29 14:37:07 2015] php5-fpm[11917]: segfault at 7f41c9dd22bd ip 00007f41ccaea13a sp 00007ffcc5730ce0 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
[Wed Jul 29 14:37:54 2015] php5-fpm[12083]: segfault at 7f41c9db72bd ip 00007f41ccaea13a sp 00007ffcc5730ce0 error 4 in libmemcached.so.10.0.0[7f41ccad2000+32000]
而谷歌搜索这个相同的问题,并努力寻找一个解决方案,是不相关的会话(因为我已经排除了)也不坏PHP代码(因为我有几个网站运行完全相同的版本的WordPress,没有问题…(除了一个),我得到了一个答案,告诉我一个可能的解决方案确实涉及删除一些有bug的扩展(通常是memcache/d,但也可能是其他东西)。
因为这个网站在一个Ubuntu服务器上运行得很好,当切换到一个新的服务器时,我立即怀疑是从PHP 5.5迁移到PHP 7导致了这个问题。这很奇怪,因为没有其他网站受到影响。然后我想起了新服务器的另一个不同之处:我还安装了new Relic。这既是一个扩展,也是一个小型服务器,在后台运行,并发送大量的分析数据到New Relic进行处理。据称,这是一个PHP 5扩展,但令人惊讶的是,它也可以很好地加载PHP 7。
现在棘手的部分来了。在某个时候,我为那个特定网站的WordPress安装了W3 Total Cache。随后,我发现该服务器的性能非常出色,以至于不需要W3TC,所以我坚持使用一个简单得多的配置。所以我可以卸载W3TC。这些都很好,但是……我忘了我也在W3TC上打开了New Relic(据称,它增加了一些额外的分析数据发送到New Relic)。卸载W3TC时,可能在我的服务器的New Relic配置上留下了"一些东西",它仍然试图通过W3TC接口发送数据(假设W3TC有一个接口……)我真的不知道它是如何在那个级别上工作的),而且,因为那个特定的代码位丢失了,该网站的php_fpm处理程序会失败……有时候。没有所有的时间,因为我假设,在大多数情况下,nginx发送静态页面返回。或者php_fpm,在100次调用后设置为"recycle",可能会在停止时崩溃。无论到底发生了什么,它肯定与New Relic有关-只要我从PHP中删除New Relic扩展,该网站就恢复正常工作了。
因为这是一个特殊的场景,我只是把它作为一个答案,在遥远的机会,有人在未来的谷歌搜索确切的问题。
在我的例子中,它与zend debug/xdebug有关。它将一些TCP数据包转发到IDE (PhpStorm),该IDE没有在此端口上侦听(调试关闭)。解决方案是禁用这些扩展或在调试端口上启用调试侦听。
我在安装xdebug,添加一些属性到/etc/php/7.1/fpm/php.ini并重新启动nginx后出现了这个问题。这是在Homestead Laravel盒子上运行。
简单地重新启动php7.1-fpm服务解决了这个问题。
如果PHP无法将会话信息写入文件,就会发生这种情况。默认为/var/lib/php/session
。您可以使用配置session_save_path
来更改它。
phpMyAdmin在RHEL 6上的nginx和php-fpm有问题
在我的情况下,它是Xdebug。卸载后,它恢复正常。
在我的例子中,它是由New Relic PHP Agent引起的。因此,对于导致崩溃的特定功能,我添加了以下代码来禁用New Relic:
if (function_exists('newrelic_ignore_transaction')) {
newrelic_ignore_transaction();
}
参考:https://discuss.newrelic.com/t/how-to-disable-a-specific-transaction-in-php-agent/42384/2
在我们的例子中,它是由Guzzle + New Relic引起的。在New Relic Agent变更日志中,他们提到在7.3版本中有一些Guzzle修复,但即使使用8.0也不能工作,所以仍然有一些问题。在我们的例子中,这只发生在使用Guzzle的两个脚本中。我们发现有两种解决方案:
- 在
newrelic.ini
中设置newrelic.guzzle.enabled = false
。这样你会丢失外部服务选项卡中的数据,但你可能不需要它。 将新遗迹代理降级到版本6。x也可以工作 - 如果你正在阅读这篇文章时,他们已经发布了比8.0版本更新的东西,你也可以尝试更新新遗迹代理到最新的,也许他们修复了
在我的情况下,我已经停用了缓冲函数ob_start("buffer");
在我的代码;)
一个可能的问题是PHP 7.3 + Xdebug。请将Xdebug 2.7.0beta1更改为Xdebug 2.7.0rc1或最新版本的Xdebug。
由于某种原因,当我从xdebug.ini
模式中删除profile
时,它为我修复了它。
。把
xdebug.mode=debug,develop,profile
xdebug.mode=debug,develop