邮件无缘无故地滞留在 Exim 队列中?

邮件无缘无故地滞留在 Exim 队列中?

在我的服务器上,邮件有时会延迟,显然没有什么特别的原因。

systemd-cron在此示例中,两封有关失败的 cron 作业的邮件被生成:

mailq输出(已编辑的域):

 3m  1.9K 1i6W6d-0003UT-Ut <[email protected]>
          www-data@server

 3m  1.8K 1i6W6e-0003Uh-1y <[email protected]>
          root@server

几分钟后,或者当我发出邮件时,exim -qf邮件终于被发送并送达,没有任何问题。

/var/log/exim4/mainlog(已编辑域名/IP):

2019-09-07 10:30:04 1i6W6d-0003UT-Ut <= [email protected] U=nobody P=local S=1914
2019-09-07 10:30:04 1i6W6e-0003Uh-1y <= [email protected] U=nobody P=local S=1875
2019-09-07 10:34:13 Start queue run: pid=13447 -qf
2019-09-07 10:34:14 1i6W6d-0003UT-Ut => [email protected] <www-data@server> R=smarthost T=remote_smtp_smarthost H=smtp.example.com [1.2.3.4] X=TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256 CV=yes DN="…" A=plain C="250 2.0.0 Ok: queued as 268D26139FAA"
2019-09-07 10:34:14 1i6W6d-0003UT-Ut Completed
2019-09-07 10:34:14 1i6W6e-0003Uh-1y => [email protected] <root@server> R=smarthost T=remote_smtp_smarthost H=smtp.example.com [1.2.3.4] X=TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256 CV=yes DN="…" A=plain C="250 2.0.0 Ok: queued as BA7EE6139FAC"
2019-09-07 10:34:14 1i6W6e-0003Uh-1y Completed
2019-09-07 10:34:14 End queue run: pid=13447 -qf

当我从命令行发送电子邮件时echo 'Test' | mail -s test root,邮件会立即送达,而没有开始/结束队列运行的日志条目:

2019-09-07 10:35:21 1i6WBk-0003V9-VR <= [email protected] U=root P=local S=397
2019-09-07 10:35:21 1i6WBk-0003V9-VR => [email protected] <root@server> R=smarthost T=remote_smtp_smarthost H=smtp.example.com [1.2.3.4] X=TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256 CV=yes DN="…" A=plain C="250 2.0.0 Ok: queued as 723116139F77"
2019-09-07 10:35:21 1i6WBk-0003V9-VR Completed

您知道延迟的原因吗?我怎样才能让 Exim 立即处理所有邮件?

我的配置:

  • 最新的 Debian Buster
  • exim 版本 4.92-8+deb10u2
  • 以及rootwww-data其中包括)有别名[电子邮件保护](外部的)
  • 标准 Debian exim 配置(使用update-exim4.conf

/etc/exim4/update-exim4.conf.conf

dc_eximconfig_configtype='smarthost'
dc_other_hostnames=''
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost='server'
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost='smtp.example.com::587'
CFILEMODE='644'
dc_use_split_config='true'
dc_hide_mailname='false'
dc_mailname_in_oh='true'
dc_localdelivery='maildir_home'

答案1

显然,这种情况是由 exim 和 systemd 的组合引起的如 systemd-devel 邮件列表所述

TL;DR:要从命令行发送邮件,exim 会派生一个进程来立即投递邮件。但是,由于父进程存在,此 cron 作业的 systemd 单元将终止,并且 systemd 将终止控制组中所有剩余的进程,包括之前派生的负责邮件投递的进程。

为了防止这种情况,我发现了两个解决方案(除了修复exim本身):

  • 使用 SMTP 客户端通过 TCP 发送邮件到本地 exim 守护进程,例如swaks(1)
  • 延迟 systemd 单元的结束,例如,通过exim -qf调用后调用 (queue flush) mail

这两种解决方案都不是最佳选择。第一种需要额外的软件并打开本地 tcp 连接,而第二种则需要 root 权限。目前,我将坚持使用swaks

答案2

我在发送来自 systemd 作业的邮件输出时也遇到了这个问题,所以我想问问是否有合适的解决方案。令人失望的是,我发现这个问题已经存在好几年了,而且仍然存在。

不过,对于@steiny 提供的两种解决方法,我想提供第三种解决方法。

我能猜到问题的原因,我只是sleep在邮件发送后在脚本中添加了一个计时器。它使进程保持足够长的时间以发送邮件,不需要任何额外的软件,也不需要特殊权限。

根据ArchLinux wiki 中的 systemd 定时器我写了一个 shell 脚本来模拟 Cron 的 MAILTO 功能。它与 wiki 版本基本相同,结尾为:

# If we doo not sleep the mail gets stuck in the queue
sleep 10

我没有对所需时间进行任何测试。但我从 10 秒开始测试理论,它有效,而且由于它只在后台运行,所以让它等待那么长时间没有问题。

答案3

由于某些错误(例如 DNS 解析失败),邮件可能会滞留在 exim 的队列中。如果您使用的是 Gmail,这可能是由 Google 的 IPv6 反向 DNS(PTR 记录)策略引起的,因为特克特恩在他的回答中提到这里。因此,解决方案是禁用 Google SMTP 服务器的 IPv6 查找。

如果您使用“拆分”exim 配置,只需以 root 身份执行以下操作:

echo "dns_ipv4_lookup = *google.com : *gmail.com" > /etc/exim4/conf.d/main/90_exim4-gmail_disable_ipv6
update-exim4.conf
systemctl restart exim4

相关内容