我注意到手册中有以下简介:
刷新完整队列的最佳方式是使用如下命令行:
/usr/sbin/sendmail -OQueueSortOrder=filename -q10m -d99.100
/usr/sbin/sendmail -OQueueSortOrder=random -q10m -d99.100
← V8.12 及更高版本/usr/sbin/sendmail -OQueueSortOrder=none -q10m -d99.100
← V8.13 及更高版本这里,-d99.100 告诉 sendmail 在前台运行(以便完成后您可以轻松地终止它)。-q10m 会导致队列处理守护进程每 10 分钟启动一次(与以前一样)。您需要这样做是因为在向慢速主机发送邮件时,一个守护进程似乎会挂起。通过运行并行守护进程,您可以避免这个陷阱。
在同一章的后面,它讨论了设置间隔是一个坏主意:
一小时后,服务恢复。首先,默认:
/usr/sbin/sendmail -q10m
导致 sendmail 的一个分支副本开始处理队列。但这次处理速度并不快。当队列中消息达到 30,000 条或更多时,预读队列(打开并阅读每条消息)所需的时间将增加到 20 多分钟。[180] 而这 20 分钟仅用于预读。在这 20 分钟内不会发送任何邮件。此后,情况变得更糟。十分钟后,第二个 sendmail 守护进程被分叉,它也开始预读队列。现在,不再是一个 sendmail 守护进程打开并读取队列中的所有消息,而是有两个 sendmail 守护进程并行执行相同的操作。
与您想象的相反,磁盘上的两倍 I/O 并不意味着速度快两倍。磁盘是有限的设备,每秒只能进行有限数量的磁头移动[181],并且每秒只能传输固定数量的字节。由于两个 sendmail 守护进程彼此之间相差 10 分钟,因此每个守护进程都在读取和处理单独的文件。根据内存磁盘缓存的大小,任何一个守护进程都不太可能利用这种缓存的效率。简而言之,两个 sendmail 守护进程并行处理深队列比单个 sendmail 守护进程单独处理同一个队列要差。
如果这还不够的话,再过 10 分钟,第三个 sendmail 守护进程就会开始处理队列。
到现在为止,第一个 sendmail 守护进程可能已经完成了队列的预读,并且可能已经开始发送消息。但即使它已经完成了,现在也有三个 sendmail 守护进程正在处理这个单一的深层队列,并且发生了一件奇怪的事情。由于保存队列的磁盘是有限的,因此添加第三个 sendmail 守护进程会减慢前两个守护进程的运行速度。第二个守护进程预读队列的时间不再是 20 分钟,而是 30 分钟。
这意味着每 10 分钟就会有另一个 sendmail 队列处理守护进程加入到队列中。随着每个守护进程的加入,每个进程都会减慢其他已在运行的守护进程的速度,不久之后,机器上的负载就会开始上升,而消息传递的速度则会以惊人的速度下降。事实上,当这种行为发生在一个流量很大的站点上时,sendmail 队列处理守护进程可能会启动,而且似乎永远也完成不了。
所以我觉得我在文档中读到了两件完全不同的事情:
- “嘿!如果你的队列很大,请将队列运行器设置为每 10 分钟启动一次!”
- “嘿!如果你的队列很大,无论你做什么,都不要将队列运行器设置得太短,否则会减慢速度。”
对于大型队列,应采取什么适当的措施?
答案1
您所看到的是典型的 sendmal-ish“仅修复一个问题,忽略其他可能的问题” - 这是由数十年的“我做出贡献来解决我的问题”发展造成的。
第一条建议处理相当大的(但不是很大)队列中的“处理缓慢”的项目。
第二条建议处理巨大的队列处理,这使得默认的 sendmail 队列运行设置难以置信速度慢,占用内存大。
第一个建议可以通过使用* MinQueueAge
- 时间来改进之间特定邮件的投递尝试。
* MaxQueueRunSize
- 队列运行器处理的最大邮件数。
旧 RFC 建议投递尝试间隔 30 分钟。其他 MTA 可以根据队列中花费的时间在投递尝试之间使用不同的延迟。BTW
处理 MSA 队列和主队列应该分别进行优化。
恕我直言: 大多数非大型网站可以手动处理巨大的队列。最常见的原因是由于黑客/漏洞导致的垃圾邮件“每隔几年一次”。优化 sendmail 以更快地发送邮件是没有意义的。请参阅MSA 队列报告中有 18GB。