我正在调查 3 台 CentOS 机器上用作 MongoDB 副本集的奇怪行为,其中一台还托管使用 MongoDB 副本集的 PHP Web 应用程序。基本设置如下:
- 节点 1:CentOS 5.8、MongoDB 2.6.10(作为 PRIMARY)、Apache 2.2.23(运行带有 MongoDB 驱动程序 1.6.10 的 PHP Web 应用程序)
- 节点 2:CentOS 5.11、MongoDB 2.6.10(充当 SECONDARY)、Apache 2.2.23(只运行一个空的 index.html,每隔几分钟由 Nagios 调用一次)
- 节点 3:CentOS 5.11、MongoDB 2.6.10(充当 SECONDARY)、Apache 2.2.23(只运行一个空的 index.html,每隔几分钟由 Nagios 调用一次)
现在,它们都经历了几乎持续 100% 的 CPU 负载。负载是由启动大量 httpd 进程引起的。即使在几乎没有 HTTP 流量的节点 2 和 3 上也是如此。mongod 进程的 CPU 使用率在每台机器上都小得可怜。
top
节点 2 上的输出如下:
节点 1 和 3 上的输出看起来非常相似。节点 2 上的 httpd 访问日志如下所示:
有大量 httpd 进程,但实际 HTTP 请求数量却很少,这对我来说似乎很奇怪。当我检查netstat -p
节点 2 时,我看到了类似以下内容:
打开的 mongod 套接字应该是复制工作者或者副本集心跳,但输出中真正引人注目的是netstat -p
:来自其对应节点(节点 3)上的 MongoDB 端口 27017 的额外打开的 httpd(?!)套接字数量。
因此,登录机器(例如通过 SSH)一段时间后会变得非常慢。重新启动 httpd 在短期内有效,httpd 进程数和 CPU 负载会立即降至正常水平。但几个小时后,httpd 进程/套接字再次填满,机器的 CPU 负载又回到 100%。重新启动 httpd 对副本集的运行没有任何影响。
我不确定,但我猜测 Apache 的 prefork/worker 配置没什么特别的:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
长话短说……
- 它真的是 MongoDB 副本集吗?它以某种方式影响了 Web 服务器,为什么?
- Apache(httpd)为什么关心这些随机的 37000 ~ 60999 端口上的套接字嗡嗡声?(它不应该只处理端口 80/443 吗?)
- 我该怎么做才能解决或至少隔离该问题?
答案1
事实证明,大量的 httpd 进程、打开的连接以及随之而来的高 CPU 负载在某种程度上是由于VirtualHost
Apache 文件conf.d
夹中的旧的和损坏的 SSL 配置(重复的不同的过期证书)造成的。
由于没有任何错误消息,我反复检查了配置,并进行了一些反复尝试。删除 SSL 配置导致启动的 httpd 进程数量大幅下降,并且连接保持打开状态。CPU 负载降至正常水平。
问题已经解决,无论这种奇怪的现象是从何而来,以及损坏的 SSL 配置与此有何关系。尽管如此,我仍然对 MongoDB 副本集成员和 httpd 套接字之间仍然出现的奇怪关系感到疑惑netstat -p
。