Apache 线程停止在状态 ..reading.. 直到达到 TimeOut 的 http.conf 值

Apache threads stops in state ..reading.. until http.conf value of TimeOut is reached

当我检查网络服务器 mod_status /server-status 时,我注意到有一堆线程处于状态 ..reading..

在线程上执行 strace 这就是线程处于 ..reading.. 时实际发生的情况

...
...
semop(327681, {{0, 1, SEM_UNDO}}, 1)    = 0    
gettimeofday({1452260985, 867058}, NULL) = 0
getsockname(156, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("172.31.9.248")}, [16]) = 0
fcntl(156, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl(156, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
gettimeofday({1452260985, 867479}, NULL) = 0
read(156, 0x558f4c26e9d8, 8000)         = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=156, events=POLLIN}], 1, 300000) = 1 ([{fd=156, revents=POLLIN}])
read(156, "", 8000)                     = 0
gettimeofday({1452261254, 669634}, NULL) = 0
gettimeofday({1452261254, 669691}, NULL) = 0
shutdown(156, SHUT_WR)                  = 0
poll([{fd=156, events=POLLIN}], 1, 2000) = 1 ([{fd=156, revents=POLLIN|POLLHUP}])
read(156, "", 512)                      = 0
close(156)                              = 0
read(6, 0x7fff901f67e7, 1)              = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1452261254, 670341}, NULL) = 0    
semop(327681, {{0, -1, SEM_UNDO}}, 1)   = 0
...
...

当线程处于 ..waiting.. 时,strace 在以下行停止:

poll([{fd=156, events=POLLIN}], 1, 300000) = 1 ([{fd=156, revents=POLLIN}])

在这种情况下,"Timout" 的 apache 配置值设置为 30,反映值“300000”。 这是它等待的超时值,降低配置值将更改上面显示的值,这将使超时更快。

根据我使用 strace 的新知识,在我看来它试图获取一个套接字来查找内部 IP 地址。但这并不成功。 设置 "HostnameLookups" 已关闭。

检查我们的生产环境表明,当 Apache 停止在 ..reading.. 时它具有相同的模式,但随后它显示了 IPV6 地址模式。

示例:

getsockname(154, {sa_family=AF_INET6, sin6_port=htons(80), inet_pton(AF_INET6, "::ffff:172.31.3.239", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0

然后在 "poll" 处停止,然后如上例所示获取“(超时)”。

但是是否有一些输入为什么它在 ..waiting.. 中停止?

"Resource temporarily unavailable"留言是否留下任何线索?

如果重要的话,Apache 运行 在亚马逊云中 ELB 后面的 EC2 实例上。

更新: 下图显示了生产服务器现在如何使用线程状态。很多..阅读.. Image of Apache thread states

我们还在服务器上 运行 大量 VirtualHosts 如果这能提供任何线索为什么会发生这种情况。

万维网上最近的线程我遇到同样的问题是这个:http://apache-http-server.18135.x6.nabble.com/Apache-Hangs-Server-Status-shows-all-Reading-td4751342.html

它正在轮询其套接字,等待其中一个或多个变得可读,或者等待读取超时到期。

But is there some input why it stops in ..waiting.. ?

没有任何输入。这就是它阻塞的原因。

线程卡在..reading.. 是由于 ELB 中的连接设置 "Idle Timeout" 与 http.conf

中的 Keepalivetimout 设置不匹配造成的

ELB 中设置的连接超时时间比 Apache 配置中设置的 Keepalivetimout 长很多。这导致 Elastic Load Balancer 将尝试保持打开的连接,而 Apache 想要关闭它。 看这里http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/config-idle-timeout.html

更改 ELB 设置以匹配 Apache 配置中的设置后(当前为 60 秒)给出的结果是我没有得到一长串处于 R(读取)状态的线程。它们现在处于状态 K(保持活动状态)。 这看起来更像是线程的预期行为。