最近,我遇到一个 postfix 邮件服务器由于高负载(即 CPU 使用率高)而无响应。
这意味着控制台和 ssh 登录由于负载而未完成。
监控显示 CPU 使用率 100%,而 I/O 仍然中等。
硬重置后,系统日志中的最后日志行显示:
Feb 06 09:37:16 example.org postfix/master[10461]: warning: unix_trigger_event: read timeout for service private/tlsmgr
Feb 06 10:04:58 example.org kernel: systemd-journal invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=-250
[..]
Feb 06 10:04:59 example.org kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/dnf-makecache.service,task=dnf,pid=1584309,uid=0
Feb 06 10:04:59 example.org kernel: Out of memory: Killed process 1584309 (dnf) total-vm:944600kB, anon-rss:817340kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:1772kB oom_score_adj:0
[..]
Feb 06 10:04:56 example.org dovecot[10353]: master: Warning: Time moved forwards by 5.880984 seconds - adjusting timeouts.
[..]
Feb 06 09:41:36 example.org systemd-networkd[10273]: enp0s3: Failed
[^--- sic, yes, shows up out-of-order in journalctl output]
Feb 06 10:04:56 example.org postfix/master[10461]: warning: unix_trigger_event: read timeout for service public/pickup
[..]
Feb 06 10:04:56 example.org dovecot[10353]: master: Error: service(imap-login): Initial status notification not received in 30 seconds, killing the process
Feb 06 10:04:56 example.org dovecot[10362]: imap-login: Fatal: master: service(imap-login): child 1584458 killed with signal 9
Feb 06 10:04:56 example.org postfix/tlsmgr[10953]: warning: end-of-input while reading request from tlsmgr socket: Broken pipe
[.. many repeats of above message ..]
Feb 06 10:05:03 example.org postfix/tlsmgr[10953]: warning: end-of-input while reading request from tlsmgr socket: Broken pipe
Feb 06 10:05:03 example.org postfix/tlsmgr[10953]: warning: end-of-input while reading request from tlsmgr socket: Application error
[.. many repeats of above message ..]
Feb 06 11:22:01 example.org postfix/tlsmgr[10953]: warning: end-of-input while reading request from tlsmgr socket: Application error
Feb 06 11:22:01 example.org postfix/tlsmgr[10953]: warning: end-of-input while reading request from tlsmgr socket: Application error
Feb 06 11:22:27 example.org systemd-journald[10176]: [
答案1
根本原因是系统内存不足,因此,为了使系统更加健壮,应该降低该事件发生的概率。特别是通过:
- 限制核心服务的内存使用,例如通过限制 Golang DB 连接池中的并发数据库连接数量、限制邮件服务器中的附件大小、设置应用程序内存/缓存限制等。
- 禁用多余的服务
- 可能会向该系统添加更多 RAM
此外,人们可能会致力于改善相关组件在接近 OOM 条件和(相对)内存不足的情况下的故障模式,例如:
- 改进 dnf(或 microdnf,预定的 dnf 后继者),使其可以在 RAM 小于 2 GiB 的系统上使用 - 以及可用于此类内务管理实用程序的可用内存小于 1 GiB 的系统,其消耗应该少得多用于日常任务的内存超过 800 MiB
- 改进 systemd-networkd,使其不会在 OOM 情况下关闭网络接口
- 改进 Postfix,以便 tlsmgr 及其客户端从接近 OOM 的情况中快速恢复,例如通过放弃过时的 epoll 事件,而不是用多余的错误消息和处理淹没和占用系统