内存不足时如何保持SSH打开
How to keep SSHD open when out of memory
我在 EC2 t2.small 实例 (2GB RAM) 上,一直被锁定在服务器外部,无法通过 ssh 进入。
错误消息是 ssh_exchange_identification: read: Connection reset by peer
了解该应用程序后,我假设它会泄漏内存并且 SSHD 会因此而阻塞。
有没有办法允许 SSH 连接到 RAM 已满的 linux 盒子?
我可以让 SSHD 为新连接保留足够的内存吗?
虽然您无法为 sshd
预分配内存,但您可以为应用程序设置内存限制,使其无法占用所有内存。请参阅 man ulimit
如何执行此操作。
如果它是 Java 应用程序,请尝试 -Xmx
设置它可以分配的最大内存量。
当服务器遇到内存不足时,它通常会杀死几个由OOM(out of memory) Killer 控制的应用程序。在您的情况下,当您的服务器内存不足时,它会终止 SSH 进程以释放内存。我们可以通过为 ssh 进程禁用 OOM 杀手来避免这种情况:
为任何进程禁用 OOM 杀手:
echo -17 > /proc/`pidof Process`/oom_adj
为 ssh 所有进程禁用 OOM Killer:
pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; done
要自动执行此操作,我们需要将 crontab 设置为 1 分钟
*/1 * * * * root pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; done
您可以阅读有关 Linux OOM 杀手 here 的更多信息。
当用户 space 进程使系统 运行 虚拟内存不足时,内核中不会终止进程。通常 运行ning out of memory 转化为一些试图增长但由于缺乏内存资源而无法增长的进程(malloc(3) 在 [=18 上失败=]sbrk(2))
通常,所有程序或多或少都设计为以某种方式处理此类错误,但通常(因为内存对它们 运行 至关重要)它们决定以某种方式终止。 sshd(8) 也会发生这种情况。
解决此问题的昂贵方法是向您的系统添加物理内存,但如果您不想这样做,还有另一种更便宜的方法,但有点令人生畏:将交换 space 添加到您的系统 。请记住,虚拟内存由真实的物理内存和虚拟的、非真实的辅助存储内存组成。将交换添加到您的系统,至少要测试这是否是问题所在。
另一种可能的解决方案是分配一些 ZRAM。
如果您不使用 SWAP 文件(由于磁盘限制)并且 RAM 非常有限,这将有所帮助。
ZRAM 需要一些计算成本,因为内存项每次 written/read 来自 RAM 时都需要 compressed/decompressed。
但完全有可能仅通过 RAM 压缩来增加 300 到 500MB 的 RAM。
托管您的 GUI 和其他后台进程数据可能就足够了。
我在 EC2 t2.small 实例 (2GB RAM) 上,一直被锁定在服务器外部,无法通过 ssh 进入。
错误消息是 ssh_exchange_identification: read: Connection reset by peer
了解该应用程序后,我假设它会泄漏内存并且 SSHD 会因此而阻塞。
有没有办法允许 SSH 连接到 RAM 已满的 linux 盒子?
我可以让 SSHD 为新连接保留足够的内存吗?
虽然您无法为 sshd
预分配内存,但您可以为应用程序设置内存限制,使其无法占用所有内存。请参阅 man ulimit
如何执行此操作。
如果它是 Java 应用程序,请尝试 -Xmx
设置它可以分配的最大内存量。
当服务器遇到内存不足时,它通常会杀死几个由OOM(out of memory) Killer 控制的应用程序。在您的情况下,当您的服务器内存不足时,它会终止 SSH 进程以释放内存。我们可以通过为 ssh 进程禁用 OOM 杀手来避免这种情况:
为任何进程禁用 OOM 杀手:
echo -17 > /proc/`pidof Process`/oom_adj
为 ssh 所有进程禁用 OOM Killer:
pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; done
要自动执行此操作,我们需要将 crontab 设置为 1 分钟
*/1 * * * * root pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; done
您可以阅读有关 Linux OOM 杀手 here 的更多信息。
当用户 space 进程使系统 运行 虚拟内存不足时,内核中不会终止进程。通常 运行ning out of memory 转化为一些试图增长但由于缺乏内存资源而无法增长的进程(malloc(3) 在 [=18 上失败=]sbrk(2))
通常,所有程序或多或少都设计为以某种方式处理此类错误,但通常(因为内存对它们 运行 至关重要)它们决定以某种方式终止。 sshd(8) 也会发生这种情况。
解决此问题的昂贵方法是向您的系统添加物理内存,但如果您不想这样做,还有另一种更便宜的方法,但有点令人生畏:将交换 space 添加到您的系统 。请记住,虚拟内存由真实的物理内存和虚拟的、非真实的辅助存储内存组成。将交换添加到您的系统,至少要测试这是否是问题所在。
另一种可能的解决方案是分配一些 ZRAM。
如果您不使用 SWAP 文件(由于磁盘限制)并且 RAM 非常有限,这将有所帮助。
ZRAM 需要一些计算成本,因为内存项每次 written/read 来自 RAM 时都需要 compressed/decompressed。
但完全有可能仅通过 RAM 压缩来增加 300 到 500MB 的 RAM。 托管您的 GUI 和其他后台进程数据可能就足够了。