为什么我的 httpd mpm_prefork 进程被收割得这么快?

为什么我的 httpd mpm_prefork 进程被收割得这么快?

[编辑]

大部分情况下,这个问题都不太好 - 请参阅我的回答

[/编辑]

我们有一个运行 RHEL6、x64 的系统。我们正在使用来自源代码的 apache 2.2.22 的本地安装。我们主要服务于:

  1. mod_perl 应用程序(本地安装 perl 5.16.0)
  2. 使用 mod_jk 代理的 tomcat 应用程序

这里是一些背景信息;主要问题如下。

所有这些都与 Oracle 后端对话。

我们遇到了 Oracle 变得无响应的问题。我们认为这是因为我们达到了 Oracle 中的最大进程限制。我们已经提高了进程限制,但现在 Oracle 服务器上的内存压力很大。我们有大量 Oracle 会话处于空闲状态。我可以将它们中的很多追溯到 httpd 进程。

我们让 mod_perl 的 Apache::DBI 为每个生成的 httpd 子进程启动一个到数据库的新连接。我们担心,当 httpd 退出时,这些连接并不总是能正确关闭……而 httpd 正在退出非常经常。我知道修改 mod_perl 应用程序以使用更好的数据库连接池形式会很好;我们计划这样做,但希望尽快解决我们眼前的问题。

这是主要问题。

我们正在使用 prefork MPM。

Apache 子进程最多持续几分钟日志分析表明,每个子进程在退出前服务的客户端少于 50 个;每个子进程服务的最后一个请求是OPTIONS * HTTP/1.0在某种内部连接上;我的印象是,这是来自主进程的“ping”。

我已经调整了 MPM 配置,如下所示。我不想将 MinSpareServers 调得太高,因为毕竟我正在尝试最小化与 oracle 的会话数量。

MinSpareServers       5
MaxSpareServers       30
MaxClients            150
MaxRequestsPerChild   10000

目前我们每分钟处理 250-300 个请求。

我们有 21 个 httpd 正在运行,其中最老的(除 master 之外,由 root 拥有)已经运行了 3 分钟。

这种对阿帕奇儿童的收割率确实看起来太高了。这可能是什么原因造成的?

Apache 的构建基于:

  $ ./configure --prefix=/opt/apache --with-ssl=/usr/lib --enable-expires --enable-ext-filter --enable-info --enable-mime-magic --enable-rewrite --enable-so --enable-speling --enable-ssl --enable-usertrack --enable-proxy --enable-headers --enable-log-forensic

Apache 配置信息:

% /opt/apache/bin/httpd -V
Server version: Apache/2.2.22 (Unix)
Server built:   Jul 23 2012 22:30:13
Server's Module Magic Number: 20051115:30
Server loaded:  APR 1.4.5, APR-Util 1.4.1
Compiled using: APR 1.4.5, APR-Util 1.4.1
Architecture:   64-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/opt/apache"
 -D SUEXEC_BIN="/opt/apache/bin/suexec"
 -D DEFAULT_PIDLOG="logs/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="logs/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

模块被编译到 apache 而不是共享库中:

% /opt/apache/bin/httpd -l
Compiled in modules:
  core.c
  mod_authn_file.c
  mod_authn_default.c
  mod_authz_host.c
  mod_authz_groupfile.c
  mod_authz_user.c
  mod_authz_default.c
  mod_auth_basic.c
  mod_ext_filter.c
  mod_include.c
  mod_filter.c
  mod_log_config.c
  mod_log_forensic.c
  mod_env.c
  mod_mime_magic.c
  mod_expires.c
  mod_headers.c
  mod_usertrack.c
  mod_setenvif.c
  mod_version.c
  mod_proxy.c
  mod_proxy_connect.c
  mod_proxy_ftp.c
  mod_proxy_http.c
  mod_proxy_scgi.c
  mod_proxy_ajp.c
  mod_proxy_balancer.c
  mod_ssl.c
  prefork.c
  http_core.c
  mod_mime.c
  mod_status.c
  mod_autoindex.c
  mod_asis.c
  mod_info.c
  mod_cgi.c
  mod_negotiation.c
  mod_dir.c
  mod_actions.c
  mod_speling.c
  mod_userdir.c
  mod_alias.c
  mod_rewrite.c
  mod_so.c

最后要注意的一点 - red hat httpd、apr 和 perl 包都已安装,但 ldd 显示这些库均未与正在运行的 httpd 链接。

答案1

啊啊啊

在这种情况下,答案是没有使用 maxrequestsperchild、minspareservers 和 maxspareservers 选项配置 apache。

我修改了一个配置文件,我认为它应该Include在主文件中,但实际上不是。我是这个网站的新手,配置又旧又乱。唉。

因此,我描述的行为是编译后的默认行为(我三重检查;它没有在其他任何地方设置)。文档表明这些是编译后的默认行为:

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxrequestsperchild

http://httpd.apache.org/docs/2.2/mod/prefork.html

MaxRequestsPerChild 10000
MaxSpareServers 10
MinSpareServers 5

我认为我看到的行为与这些默认值不一致。我会向 apache 提交错误报告。

我想这仍然是一个有用的问题,可以留在网站上,因为默认行为与文档不符。如果其他人不同意,我很乐意关闭我的问题。

相关内容