AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 527007
Accepted
BurninLeo
BurninLeo
Asked: 2013-07-30 04:13:26 +0800 CST2013-07-30 04:13:26 +0800 CST 2013-07-30 04:13:26 +0800 CST

Apache mpm-worker + mod_fcgid + php5_cgi 部分和零星地下降

  • 772

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

总体而言,服务器运行稳定且快速。但是,有时某些用户会在几分钟内无法访问该页面。

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

工作假设 2 是 MaxRequestsPerProcess 负责。在 500 次调用之后,进程尝试关闭,mod_fcgid 不会优雅地终止,并且在进程等待终止时,将进一步的客户端分配给该进程(并被该进程拒绝)。但我无法想象 Apache 会如此愚蠢。

我的问题是:除了一些错误日志中没有任何内容

[warn] mod_fcgid: process ???? graceful kill fail, sending SIGKILL

我已经没有想法在哪里追踪问题了。它偶尔出现,我还没有设法激怒它。服务器性能(CPU/RAM)应该不是问题,因为最近几周整体负载一直在较低的范围内。

感谢您的任何提示。关于我的假设的任何评论(这并没有帮助我找到解决方案,但是 - 我试图禁用 MaxRequestsPerProcess 但还不知道它是否有帮助)?我将非常感谢一些如何追踪这个问题的想法。

阿帕奇配置

    <Directory /var/www/html>
           ...

            # PHP FCGI
            <FilesMatch \.php$>
                    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>

阿帕奇模块配置

<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 小时,因为很少,应用程序可能需要一些时间来运行(例如,执行数据库优化的每晚 cronjob)。

启动脚本

#!/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
  • libapache2-mod-fcgid: 1:2.3.6-1.1
  • php5-common: 5.3.10-1ubuntu3.7
apache-2.2
  • 2 2 个回答
  • 1559 Views

2 个回答

  • Voted
  1. Best Answer
    mc0e
    2013-08-15T05:29:47+08:002013-08-15T05:29:47+08:00

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

    当您的服务器不可用时,很可能 php 工作进程都很忙,但这只是一个近因。某些事情正在减慢您的服务器速度,至少在一段时间内,php 进程无法跟上传入的请求。是什么让你的服务器变慢很难判断,但“优雅的终止失败”让我认为要被终止的进程可能正在磁盘上等待。

    发生这种情况时您是否已登录?系统感觉反应灵敏吗?

    在顶部,查看进程状态,并查找正在等待 IO 的“D”状态。这些有很多吗?顶部摘要中的“wa”是进程在等待 IO 上花费的总时间。(它表示百分比,但这可能是一个处理器时间的百分比)。iotop、atop 和 vmstat 等工具也可能有助于了解哪些进程是磁盘绑定的,以及磁盘限制整体性能的程度。

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

    杀死工作人员之前的 1000 个请求很高。我建议将其降低到 10 到 50 之间。

    • 1
  2. Andrew B
    2013-08-15T05:50:15+08:002013-08-15T05:50:15+08:00

    我认为你在假设 1 的正确轨道上。mc0e 的建议非常可靠,所以我主要是添加它。

    您看到的这些日志消息表明各个进程在prefork MPM 下被锁定,这为您提供了比worker更好的进程隔离。我以前在生产环境中看到过这种情况,这意味着您有一些行为不端的代码。

    在每个孩子的最高请求和挂起进程之间,这为内存膨胀奠定了基础。该文档特别涵盖了一个事实,即非零值有助于防止内存泄漏,但是如果您将该值设置得太高,则会失去好处。让你的进程挂在上面只会进一步增加整体内存占用。

    这给你留下了两个直接的收获:

    • 正如mc0eMaxRequestsPerChild所暗示的那样,大幅下降。这有助于防止各个进程的生存时间足够长以累积大量内存泄漏……但正如他所说,20-30M 可能没什么大不了的。
    • 找到你的错误。您正在寻找内存泄漏和执行死锁(如 mc0e 所建议的资源争用,但还要查看当网络资源无法访问或无响应时您的代码会做什么)。lsof在大型进程上运行可能会根据代码正在执行的操作提供提示(即文件句柄泄漏,并且达到最大文件句柄上限可能与进程死锁有关),否则您正在查看代码调试。
    • 1

相关问题

  • Apache Django Mod_Wsgi - 自动重新加载应用程序

  • Apache:对多个虚拟主机使用相同的目录指令

  • Apache 上的子域不工作 - 找不到服务器

  • PHP 作为 CGI 还是 Apache 模块?

  • 避免将某些丢失的文件记录到 Apache2 错误日志中

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve