首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apache worker+ mod_fcgid + php5_cgi部分和零星下降

Apache worker+ mod_fcgid + php5_cgi部分和零星下降
EN

Server Fault用户
提问于 2013-07-29 12:13:26
回答 2查看 1.6K关注 0票数 1

最近,由于内存问题,我已经从Apache预叉(PHP模块)更改为mpm-worker (PHP)。我正在运行一个相当大的PHP应用程序,每个预分叉进程需要20-30米。

总的来说,服务器运行稳定且快速。但是,有时,某些用户在几分钟内无法使用该页面。

工作假设1(=粗略的想法)是,其中一个进程(通常是2个,有时高达5或6个)挂起,分配给该进程的每个客户端(例如,50%的客户端)都会收到错误消息。

工作假设2是MaxRequestsPerProcess负责。在500个调用之后,进程试图关闭,mod_fcgid不会优雅地终止,而当进程等待终止时,更多的客户端被分配给(并被进程拒绝)。但我不能想象阿帕奇会这么蠢。

我的问题是:错误日志中除了一些

代码语言:javascript
复制
[warn] mod_fcgid: process ???? graceful kill fail, sending SIGKILL

我想不出什么办法去追踪这个问题了。它似乎偶尔出现,我还没有设法激怒它。服务器性能(CPU/RAM)不应成为问题,因为总体负载在最近几周的较低范围内。

谢谢你的暗示。对我的假设有什么评论(这无助于我找到解决方案,但我试图禁用MaxRequestsPerProcess,但还不知道它是否有帮助)?我将非常感谢一些如何跟踪这个问题的想法。

Apache配置

代码语言:javascript
复制
    <Directory /var/www/html>
           ...

            # PHP FCGI
            <FilesMatch \.phpA3gt;
                    SetHandler fcgid-script
            </FilesMatch>
            Options +ExecCGI
    </Directory>

    <IfModule mod_fcgid.c>
            FcgidWrapper /var/www/php-fcgi-starter .php
            # Allow request up to 33 MB
            FcgidMaxRequestLen 34603008
            FcgidIOTimeout 300
            FcgidBusyTimeout 3600
            # Set 1200 (>1000) for PHP_FCGI_MAX_REQUESTS to avoid problems
            FcgidMaxRequestsPerProcess 1000
    </IfModule>

Apache模块配置

代码语言:javascript
复制
<IfModule mod_fcgid.c>
  AddHandler    fcgid-script .fcgi
  FcgidConnectTimeout 20
  FcgidBusyTimeout 7200

  DefaultMinClassProcessCount 0
  IdleTimeout 600
  IdleScanInterval 60
  MaxProcessCount 20

  MaxRequestsPerProcess 500
  PHP_Fix_Pathinfo_Enable 1
</IfModule>

注意:超时设置为2小时,因为很少情况下,应用程序可能需要一些时间来运行(例如,执行数据库优化的夜间任务)。

初学者脚本

代码语言:javascript
复制
#!/bin/sh
PHP_FCGI_MAX_REQUESTS=1200
export PHP_FCGI_MAX_REQUESTS

export PHPRC="/etc/php5/cgi"
exec /usr/bin/php5-cgi

#PHP_FCGI_CHILDREN=10
#export PHP_FCGI_CHILDREN

包版本

  • 系统: Ubuntu 12.04.2 LTS
  • apache2-mpm-worker: 2.2.22-1ubuntu1.4
  • 利洗礼2-mod-fcgid: 1:2.3.6-1.1
  • 第5阶段-共同:5.3.10-1 ubuntu3.7
EN

回答 2

Server Fault用户

回答已采纳

发布于 2013-08-14 13:29:47

我认为每个进程20到30 as是相当小的。这一切都是相对的,但例如,大多数CMS应用程序至少需要100‘s。此外,您的最大上传大小将受到最大进程大小的限制,如果这是重要的。

当您的服务器不可用时,可能php工作进程都很忙,但是这只是一个直接原因。服务器的速度减慢了,至少在一段时间内,php进程无法跟上传入的请求。什么在减慢您的服务器是很难判断,但‘优雅的杀死失败’让我认为,被杀死的进程很可能在磁盘上等待。

这事发生的时候你登录了吗?系统是否有反应?

在顶部,查看流程状态,并查找等待IO的“D”状态。有很多这样的吗?顶部汇总中的“wa”是进程在IO上等待的总时间。(上面写着百分比,但这很可能是一个处理器时间的百分比)。像iotop、atop和vmstat这样的工具对于查看哪些进程被磁盘绑定,以及磁盘在多大程度上限制了您的整体性能也很有用。

当工作进程无法接受新请求时,您对发生什么情况的理解是不正确的。新的请求将不会分配给它。

杀死工人前的1000个请求很高。我建议把它放在10到50之间。

票数 1
EN

Server Fault用户

发布于 2013-08-14 13:50:15

我认为你的建议是正确的。mc0e的建议是非常可靠的,所以我主要是在增加它。

您正在看到的这些日志消息表明,单个进程正被锁定在预叉MPM下,这给您提供了比worker更好的进程隔离。我以前在生产环境中见过这种情况,这意味着您有一些错误的代码。

在你对每个孩子的最高要求和你的挂起过程之间,这就为记忆膨胀设置了舞台。文档特别涵盖了非零值有助于防止内存泄漏。这一事实,但是如果您将该值设置得太高,就会失去好处。让您的进程挂在上面,只会进一步加重整个内存占用。

这给你留下了两个即时的外快:

  • 正如MaxRequestsPerChild所暗示的,降低mc0e的幅度是很大的。这有助于防止单个进程存活足够长的时间来积累重要的记忆leaks...but,就像他说的那样,200-3000万可能不是什么大问题。
  • 找出你的虫子。您正在寻找内存泄漏和执行死锁(正如mc0e所建议的那样,资源争用,但也可以查看您的代码在网络资源变得不可访问或无法响应时所做的事情)。在大型进程上运行lsof可能会提供一个提示,这取决于代码所做的事情(即文件句柄泄漏,达到最大文件句柄上限可能与进程死锁有关),但否则您将看到代码调试。
票数 1
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/527007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档