找出什么导致与Apache&PHP&Mysql的CLOSE_WAIT连接

首先,这是一点点的背景。

我们有一个定制的PHP应用程序,运行在Apache下,支持我们的网站。

我们目前在我们的网站上遇到高stream量。 这里是我们目前的设置: – 在负载平衡器后面的10个linux web服务器(每个服务器有8个CPU,30Go RAM) – 1个linux mysql数据库服务器(30个CPU,120个RAM)

大多数情况下,stream量都保持良好状态,但是有时候由于不确定的原因,我们看到活跃的mysql连接总数飙升。 它不断泄漏,直到达到最大限度,并最终导致我们的networking用户无法使用该应用程序。

发生这种情况时,从负载平均值,内存,CPU使用率,磁盘交换的angular度来看,所有的服务器都不错。 他们有足够的资源可用。

我们确实注意到有许多Apache进程都有一个CLOSE_WAIT连接状态。 我们在其中一个Web服务器上看到大约600个进程处于该状态。

这似乎是我们遇到的问题的症状。 但是,我们有困难深入挖掘。 这是我的问题:

  • 为什么Apache挂在这些进程?
  • 有什么工具或debugging技术可以用来找出是什么原因造成的?
  • 我们应该看什么指标来了解正在发生的事情?

感谢您的帮助,

我想你有一个查询是locking一个表/一些其他的MySQL连接尝试更新比它应该更长的行。 发生这种情况时,所有传入的请求都会叠加在它后面,直到达到最大连接数。

由于请求进入而没有收到响应(由于查询在数据库中被阻塞),Apache方面也发生了同样的情况。 PHP有一个到数据库的开放连接; 它已经提出了一个查询,但尚未收到回复。 在这个时候,Apache“挂起”就是你期待它做的,因为它正在等待答案。

Apache似乎从外部(你的浏览器/移动应用程序/等)挂起,因为所有你的服务器上可用的所有孩子都卡在等待数据库答复。 实际上没有更多的连接可用。 (这也可以是负载平衡器上设置的连接限制)。 如果您尚未开始,请在负载平衡器上开始logging状态更改。 您可能会看到每个Web服务器反复上下,而“雷鸣群体”问题(稍后解释)正在发生。

我相信你在CLOSE_WAIT中的连接是一个症状,而不是一个问题。 我不会花费任何时间来解决这个问题,直到我处理了更为明显的问题(数据库)。 一旦你确定你的大量的CLOSE_WAIT将会消失,赔率就是这样。

要开始数据库方面的故障排除,您应该启用慢查询日志,如果您尚未这样做。 让它在1秒钟左右的时间内logging请求,看看问题发生时显示的内容。

注意:慢查询日志将不会logging查询,直到查询完成。 不要认为问题开始时出现的第一个查询是问题查询。 它可能会也可能不会。

现在,您可能希望一旦有问题的查询阻止其他查询完成,网站将恢复正常…

不是这样。 如果每秒有500个请求/秒,并且可以处理总共1000个请求/秒,并且您的查询locking数据库10秒钟。 现在还有5000个请求正在等待处理,除了500 /秒仍在进行之外,这就是所谓的雷鸣群体问题 。

你的问题可能完全是其他的东西,但这些是我已经处理了很多次的问题完全相同的症状,在大多数情况下,问题是阻止其他查询的数据库查询。 我遇到这个问题的唯一原因是数据库不在于CentOS(RHEL也有这个问题)。6.不幸的是,Red Hat的知识库文章只对用户讨论这个问题,但是还有其他的参考文献如果你search他们。 如果你认为这可能是这样的话,那么这个testing是非常容易的。 你只需要添加一行到你的resolv.conf 。

如果问题似乎出现在同一天/接近同一天发生的时间,则应检查您的cron作业(或其他任何正在按计划运行的作业),以查看是否从该问题查询发送。

最后,如果你确定你正在被雷鸣般的牛群问题困扰,我build议在你的负载平衡器上设置限制。 您应该对服务器进行基准testing,以大致确定可以同时处理的最大请求数,并限制负载均衡器超过连接到每个后端Web服务器的数量。

祝你好运。