PHP操作码缓存锁定Apache。也许Symfony2 - Doctrine2相关

时间:2016-02-19 08:22:15

标签: php apache symfony caching doctrine-orm

我开发了大约10个不同的网站,托管在一台服务器上,下面提到了规范。

故事

一切运行正常,直到我决定将PHP Opcode缓存集成到系统中。 我首先尝试使用APC,但是Xcache出现了同样的问题,所以我认为它与缓存程序本身无关。

系统保持稳定一段时间,从一天到一周不等,并在不同时段崩溃,但主要是在晚上23h-05h左右。 如果我重新启动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,image等文件,但它无法提供任何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网站的速度很快,没有任何操作码缓存

4 个答案:

答案 0 :(得分:5)

您是否有任何特定的cron作业在服务器崩溃时运行?

在任何情况下,如果你在日志中看到Curl_resolv_unlock: Assertion 'dns && (dns->inuse>0)' failed,这意味着你在PHP中有一个libcurl的“调试版本”,这是不好的。

您的评论提到PHP说Apache 2.0 Handler,因此它作为Apache模块运行。

当调试断言在libcurl中命中时,它会导致进程(PHP)终止。基本上我认为正在发生的是Apache的PHP处理(处理所有PHP请求)正在消亡。这就是为什么你仍然可以提供静态资源但PHP进程不断堆叠的原因。

cURL 7.26.0相当陈旧(2012年5月)。我建议安装一个较新版本的libcurl,然后用它重新编译PHP并确保cURL不是调试版本,看看是否有帮助。

答案 1 :(得分:2)

  

我的服务器API是“Apache 2.0 Handler”

你应该肯定检查PHP-FPM下是否发生了simillar行为。 Apache SAPI意味着它没有像使用FPM池进程那样与httpd的内存空间分开。

我怀疑你在某种内存泄漏上遇到了无法轻易追踪的问题。更改为FPM还可以让您在一段时间后自动重启响应者(请求数量),这比croning更加优雅和灵活,并检查流程是否运行良好。

老实说,自从我看到Apache SAPI连接PHP以来已经有一段时间了。 :)

答案 2 :(得分:0)

我无法向您推荐确切的解决方案,但我建议您trick使用解决方法来解决您的问题并提出debug提示

诀窍:你可以在监控cronjob午餐,每个5-10米通过卷曲你的一个网站请求,如果他得到否定回复或请求超时已过期(设置为你会重新启动httpd服务器+你可以清理你的cache然后重启

调试以调试您的问题,您可以从memory monitoring开始。我想问题的根源在于,在您的错误中,系统内存泄漏会导致httpd服务器崩溃,这意味着您必须使用curl等调试和处理try/catch错误。

答案 3 :(得分:0)

所以我有这个使用pthreads和curl的cron php脚本,我确实得到了。

  

php:hostip.c:693:Curl_resolv_unlock:断言`dns&&   (DNS-> INUSE&0)'失败。

所以我不确定但是你有这个选项

  

CURLOPT_DNS_USE_GLOBAL_CACHE TRUE以使用全局DNS缓存。这个   选项不是线程安全的,默认情况下处于启用状态。

将其更改为 FALSE ,即使我运行了大量线程将大量网址调用到同一位置,我也无法获得该错误...此错误确实直到我确实在快速序列中有很多请求才开始出现。