我们有一个 2.3.16 版的 dovecot 服务器,启用了 sieve duplicate 扩展来检测和丢弃重复项。我们在 Postfix virtual_aliases 文件中有重复路由,这会导致某些地址列表出现重复副本,但 Postfix 可以正确完成。
但是 Dovecot Sieve 会随机允许一些重复。不同的电子邮件在相同测试的每次迭代中都会收到重复。经过详细记录后,看起来当两个不同的 Dovecot 进程占用了相同邮箱的相同消息 ID 时,重复项就会通过。如果相同进程占用了相同邮箱的相同消息 ID 的重复项,它会正确丢弃重复项。因此,如果我将重复项减少process_limit
到 1,则在所有情况下我们都会得到零个重复项。
问题是为什么会出现“重复标记”同步问题?我是否缺少同步设置?我宁愿不要将 lmtp 进程限制设置为 1
Dovecot 配置:
service lmtp {
process_limit = 1
}
shutdown_clients = no
按照 serverfault 帖子的方向这里 我已经设置了如下所示的筛选配置,并且筛选脚本正在正确执行,并且每次都会标记重复
sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_before = /etc/dovecot/conf.d/deduplicate.sieve
sieve_extensions = +duplicate +fileinto +imapflags +editheader
去重筛选脚本:
require "duplicate";
if duplicate {
discard;
stop;
}
单个电子邮件的 Dovecot 日志条目:
Oct 12 08:57:59 lmtp([email protected])<230008><IFAiHZclKGV5ggMAfXq90w>: Debug: sieve: msgid=<SA1PR22MB3146CDDB578F27162AAD7C29EFD3A@SA1PR22MB3146.namprd22.prod.outlook.com>: Finish implicit keep action
Oct 12 08:57:59 lmtp([email protected])<230008><IFAiHZclKGV5ggMAfXq90w>: Debug: sieve: msgid=<SA1PR22MB3146CDDB578F27162AAD7C29EFD3A@SA1PR22MB3146.namprd22.prod.outlook.com>: Finishing actions
Oct 12 08:57:59 lmtp([email protected])<230008><IFAiHZclKGV5ggMAfXq90w>: Debug: sieve: msgid=<SA1PR22MB3146CDDB578F27162AAD7C29EFD3A@SA1PR22MB3146.namprd22.prod.outlook.com>: Finish duplicate_mark action
Oct 12 08:57:59 lmtp([email protected])<230008><IFAiHZclKGV5ggMAfXq90w>: Debug: sieve: msgid=<SA1PR22MB3146CDDB578F27162AAD7C29EFD3A@SA1PR22MB3146.namprd22.prod.outlook.com>: Finished executing result (final, status=ok, keep=yes)
答案1
RFC 7352非常清楚地表明哪一方应该犯错(重点是我的):
实现必须仅更新内部重复跟踪列表 当 Sieve 脚本执行成功完成时. [...] 但是,将跟踪列表的最终修改推迟到成功执行 Sieve 脚本后进行并非没有问题。这可能会导致竞争条件在更新跟踪列表之前并行传递重复消息时。这样,“重复”测试可能会漏掉重复消息。更复杂的实现可以使用锁定机制来防止此问题。但是,无论选择哪种实现,都必须防止“重复”测试错误地得出“真”的结果。
这样你就剩下一个完整的和两个不完整的解决方法:
让 Dovecot 通过 anvil 服务强制每个用户锁定lmtp_用户_并发限制=1- 这将锁定 LMTP 交付,如果锁定已被占用,则推迟回 Postfix。这应该会给你带来与你的
process_limit=1
解决方法类似的行为,但性能损失会大大降低 - 前提是你确实交付了大多对不同的用户。您可能需要查看
lmtp_connection_cache_time_limit
等。在 Postfix 中,在 Dovecot 实际以这种方式推迟消息后,查看您的延迟队列行为和连接重用 - Postfix 通常只会短暂地后退。让您的 sieve 脚本更快地完成,从而减少并发。您可能需要将昂贵的检查从 sieve 的后队列调用移到前队列过滤器。如果您要插入来自其他来源的消息,让 Dovecot 更新索引作为重复的后台作业将减少 Dovecot 在交付时可能触发的未完成工作。
让您的提交客户端在同一个事务中提交重复项,从而允许 Postfix 一起推送至 Dovecot,从而允许 Dovecot 无需锁定即可检测重复项。