我有一台 godaddy 服务器,它经常会变得不响应。很难排除故障,因为当它不响应时我无法通过 ssh 进入它。我通过添加一个 cron 作业来弄清楚发生了什么,该作业每 5 分钟将“top”的输出传送到日志文件。在它变得不响应后,我下次重新启动它时,我检查了那些日志,发现内存已用完,但交换空间基本未使用。
我正在努力减少该机器上两个应用服务器的 RAM 使用量(结果是打开了太多连接。每个连接都使用了 30m,因此在打开 40 个连接后服务器的 RAM 就用完了),但我真正想知道的是如何确保我可以 ssh 进入机器。
如果交换文件未满,那么我认为服务器有足够的空间来响应,即使它响应速度很慢。有什么方法可以保留一些内存,以便我始终可以通过 ssh 进入机器吗?
以下是服务器正常运行时的示例:
top - 15:13:21 up 3:12, 2 users, load average: 0.15, 0.30, 0.33
Tasks: 127 total, 1 running, 126 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.4%us, 1.8%sy, 0.0%ni, 95.7%id, 0.0%wa, 0.0%hi, 0.2%si, 0.0%st
Mem: 2064980k total, 1611252k used, 453728k free, 45852k buffers
Swap: 2096472k total, 0k used, 2096472k free, 790212k cached
这是服务器停止运行之前记录的最后一条日志:
top - 14:45:08 up 15:20, 0 users, load average: 0.27, 0.16, 0.10
Tasks: 141 total, 2 running, 139 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.7%us, 1.9%sy, 0.0%ni, 95.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 2064980k total, 2007652k used, 57328k free, 60496k buffers
Swap: 2096472k total, 100k used, 2096372k free, 689584k cached
请注意,当服务器内存不足时,记录“top”输出的 cron 作业也会停止运行,因此整个服务器显然会停止运行。
答案1
我以前也遇到过类似的问题,追踪起来很麻烦。由于您提供了大量信息,因此我必须详细说明需要检查的内容以及我的问题是什么。
首先,检查您的日志。在这种情况下,最值得注意的是 dmesg 的输出(这是内核环形缓冲区,它转储日志数据)。它会定期刷新到 /var/log 中的一个或多个文件中,但具体在哪里取决于您的操作系统。例如,Red Hat 有一个 /var/log/dmesg 文件。您要查找任何看起来不寻常的东西,尤其是与OOM 杀手进程。当 RAM 开始变满时,这将结束程序,以保持服务器正常运行并保持响应。sshd 应该不受此限制,但具体如何设置取决于发行版。指定 OOM 豁免的现代形式是给 sshd 一个分数,告诉内核它对整个服务器有多重要(如果发生严重的 RAM 情况,这应该会让它成为要终止的进程列表中的靠后位置)。您的发行版应该已经正确设置了它。
要检查的另一件事是您的服务器是否具有足够的熵,如下所示:
cat /proc/sys/kernel/random/entropy_avail
正常值大约在 1000-1500 以上。低于这个值,你的性能就不够了。在我的机器上,它实际上只上升到大约 4000-5000(这些是基于我对我的服务器的观察)。
我曾经在登录服务器时遇到过问题,因为服务器的熵太低(而且生成速度很慢),应用程序会挂起,等待更多的熵可用。有一个臭名昭著的 Debian Exim 错误凸显了这一点。Exim 在 Debian 上使用 GNU TLS,它只使用 /dev/random,并且每个连接都使用大量熵。请参阅这里。当熵耗尽时,Exim 就会挂起。这还会导致其他依赖熵的程序也开始拒绝连接。
由于会话密钥是每次会话生成的,因此 sshd 需要一个好的随机数源。虽然如果 /dev/random 被阻止,它应该使用 /dev/urandom 来收集伪随机数,但我不确定 sshd 是否会这样做。
这个问题在虚拟系统上可能非常严重,因为许多随机数源不会传递到虚拟机中。熵的主要来源是磁盘 I/O,但这通常不会传递到虚拟机中。可能嵌入在物理机的芯片组/CPU 中的硬件随机数生成器也不太可能传递到虚拟机中。
这对此事有一篇相当不错的报道。
我rngd
在服务器后台运行,使用以下命令将 /dev/urandom 中的数据提供给 /dev/random:
rngd -r /dev/urandom -o /dev/random
这不是一个很好的解决方案,但在您寻找更好的随机数源时,这是一个有用的技巧,可以让事情保持井然有序。我正在研究rngd
从其他来源获取数据,但目前还没有太多机会这样做。