我开发了大约 10 个不同的网站,托管在单个服务器上,其规范如下。
故事:
一切都运行良好,直到我决定将 PHP 操作码缓存集成到系统中。 我首先尝试使用APC,但是Xcache也出现了同样的问题,所以我认为这与缓存程序本身无关。
系统会在一段时间内保持稳定,从一天到一周不等,并在不同时间崩溃,但主要发生在夜间 23 点至 05 点左右。 如果我重新启动httpd服务,系统会再次稳定,在同一时间段内(1天到1周),然后再次崩溃等等...
错误报告:
这是上次崩溃期间我的 httpd 全局日志的报告:
[Thu Feb 18 20:00:11.270997 2016] [core:notice] [pid 24956:tid 139940499228480] AH00052: child pid 4522 exit signal Aborted (6)
httpd: hostip.c:693: Curl_resolv_unlock: Assertion `dns && (dns->inuse>0)' failed.
[Thu Feb 18 20:08:38.793218 2016] [core:notice] [pid 24956:tid 139940499228480] AH00052: child pid 6246 exit signal Aborted (6)
httpd: hostip.c:693: Curl_resolv_unlock: Assertion `dns && (dns->inuse>0)' failed.
[Thu Feb 18 22:12:33.576308 2016] [core:notice] [pid 24956:tid 139940499228480] AH00052: child pid 8362 exit signal Aborted (6)
httpd: hostip.c:693: Curl_resolv_unlock: Assertion `dns && (dns->inuse>0)' failed.
[Thu Feb 18 22:40:07.297428 2016] [core:notice] [pid 24956:tid 139940499228480] AH00052: child pid 10224 exit signal Aborted (6)
[Thu Feb 18 23:00:40.526867 2016] [core:warn] [pid 24956:tid 139940499228480] AH00045: child process 10846 still did not exit, sending a SIGTERM
...
请注意,服务器在 22:41:xx 左右被阻止。我在 23:00:xx 重新启动了服务器,这与此处发布的最后一行有关。
这可能与curl有关,我经常使用它,特别是PHP的curl_multi,以便通过同时启动它们来加速我的API调用。 但是,在没有安装(或禁用)任何 PHP 操作码缓存的情况下也会发生同样的错误,但它不会使服务器崩溃。
服务器状态:
当发生“崩溃”时,系统仍然可以提供任何txt、图像等文件,但不能提供任何PHP 文件。 服务器被锁定,当查看“Apache 服务器状态”时,可能有一百个请求处于“W”状态,并且随着每个传入请求的增加而增加。
缓存实现:
如上所述,我尝试使用APC和xCache,但它们都产生了同样的问题。 我的PHP是编译版本(我自己没有编译)。 所有网站上方都有 Varnish 缓存,仅缓存少数耗时的页面。 我将 Symfony2 与 Doctrine2 结合使用,并通过 Symfony2 配置在 Doctrine2 和 xcache/apc 之间建立链接:
doctrine:
orm:
auto_generate_proxy_classes: prod
auto_mapping: true
metadata_cache_driver: xcache
result_cache_driver: xcache
query_cache_driver: xcache
它似乎允许 Doctrine2 缓存实体对象并产生更好的性能(仅启用缓存对于 Doctrine2 来说是不够的)
规范:
- Debian 7.8
- Apache 2.4.12
- Mysql
- PHP 5.4.38 (compiled version)
- Varnish
- Symfony 2.4.x
任何提示或帮助都将受到极大的欢迎,因为我几个月来一直在寻找解决方案,并且在没有任何操作码缓存的情况下运行 PHP-Symfony2 网站会慢很多
最佳答案
您是否有任何特定的 cron 作业在服务器崩溃时运行?
无论如何,如果您在日志中看到 Curl_resolv_unlock: Assertion 'dns && (dns->inuse>0)' failed
,这意味着您有一个处于事件状态的 libcurl 的“调试版本”在 PHP 中这不太好。
您的评论提到 PHP 表示 Apache 2.0 Handler,因此它作为 Apache 模块运行。
当 libcurl 中的调试断言命中时,它会导致进程 (PHP) 终止。基本上我认为正在发生的事情是 Apache 的 PHP 进程(处理所有 PHP 请求)正在消亡。这就是为什么您仍然可以提供静态资源,但 PHP 进程不断堆积。
cURL 7.26.0 相当旧(2012 年 5 月)。我建议安装较新版本的 libcurl,然后用它重新编译 PHP,并确保 cURL 不是调试版本,看看这是否有帮助。
关于PHP 操作码缓存锁定 Apache 。也许 Symfony2 - Doctrine2 相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35500537/