【问题标题】:Apache mod_perl processes hang in futex_wait stateApache mod_perl 进程挂在 futex_wait 状态
【发布时间】:2011-12-07 11:04:36
【问题描述】:

我运行一个相当流行的基于浏览器的网页游戏,在 Apache (worker) 和 mod_perl 下运行。在高峰时间,当服务器每分钟处理大约 4200 个请求时,每 3-15 分钟左右一次,Apache 进程将挂起。

我已经确定这些进程卡在“FUTEX_WAIT”状态,并且似乎没有做任何事情:它们不会消耗 CPU 或在 RAM 中变得更大。但这是一个严重的问题,因为它们只是坐在那里,占用 RAM。

我当前的解决方案是一个 cron 作业,它可以剔除卡在 futex_wait_queue_me 中的 Apache 进程。但这不是很好,因为碰巧等待来自挂起的 Apache 进程的响应的用户会收到错误(500:服务器关闭连接而没有发回数据)。

我无法在我的开发机器上重现该问题,并且不知道如何进行故障排除。我很想知道:我该如何进一步诊断?

编辑:我发现问题出现在流量激增之后,当 Apache 产生更多工作进程,然后尝试剔除它们时。从孩子的角度来看,这是正常工作时的样子:

$ sudo strace -p 21764
Process 21764 attached - interrupt to quit
read(5, "!", 1)                         = 1
tgkill(21764, 21791, SIGHUP)            = 0
tgkill(21764, 21791, SIG_0)             = 0
select(0, NULL, NULL, NULL, {0, 500000}) = ? ERESTARTNOHAND (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
rt_sigreturn(0xf)                       = -1 EINTR (Interrupted system call)
munmap(0x7f9905750000, 8392704)         = 0
munmap(0x7f98f8736000, 8392704)         = 0
[...]
madvise(0x7f98e4021000, 73728, MADV_DONTNEED) = 0
exit_group(0)                           = ?
Process 21764 detached

...但偶尔会这样:

$ sudo strace -p 24133
Process 24133 attached - interrupt to quit
read(5, "!", 1)                         = 1
tgkill(24133, 24164, SIGHUP)            = 0
tgkill(24133, 24164, SIG_0)             = 0
--- SIGTERM (Terminated) @ 0 (0) ---
rt_sigreturn(0xf)                       = 0
select(0, NULL, NULL, NULL, {0, 500000}) = 0 (Timeout)
tgkill(24133, 24140, SIGUSR1)           = 0
futex(0x7f9904f4e9d0, FUTEX_WAIT, 24140, NULL

...不再继续。

我不知道如何进一步调试。

【问题讨论】:

    标签: perl apache apache2 mod-perl futex


    【解决方案1】:

    这是由于 mod-perl 中的一个错误,已修复,记录在这里:

    http://www.gossamer-threads.com/lists/modperl/dev/104026

    【讨论】:

      【解决方案2】:

      选择流量最低的时间,并在现场机器上用 strace 启动 apache,这样你就可以找到错误的原因,对于一位互联网博主来说,解决方案可以归结为

      rm /dev/random 
      mknod -m 644 /dev/random c 1 9 
      

      您可以通过使用反向代理设置来避免500: server closed connection without sending data back,因此当 apache 检测到没有数据的超时时,它会将请求转发给不同的 mod_perl 子节点

      这样,客户获得的不是 500,而是他的请求需要额外的 5 秒 (不要问我操作方法,请参阅 mod_perl/apache 指南 :)

      【讨论】:

      • 谢谢!我设法在我的开发机器上重现了这个问题,并将在上面发布更多信息。不幸的是 /dev/random 技巧似乎对我没有帮助。但我至少更先进了!
      猜你喜欢
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 2015-09-04
      • 2023-04-08
      • 2017-06-07
      • 2020-08-13
      相关资源
      最近更新 更多