POP3邮箱轮询停止工作

我们的 Discourse 服务器遇到了一个奇怪的问题。几周以来,从内部 POP3 服务器轮询邮件一直运行正常。但在 2 月 16 日,邮件接收突然停止。奇怪的是,我们在 POP3 服务器的日志文件中看到了 Discourse 的活动记录:

Feb 25 13:54:49 mailout popa3d[12458]: Authentication passed for discourse
Feb 25 13:54:49 mailout popa3d[12458]: 1545 messages (12060237 bytes) loaded
Feb 25 13:54:49 mailout popa3d[12458]: 0 (0) deleted, 1545 (12060237) left

然而,没有新的邮件被处理。

我们使用的是最新的 Discourse 版本 2.7.0.beta4(在此之前是 2.7.0.beta3)。以下是我们的邮件设置:

您是否知道可能出了什么问题?我们可以采取哪些措施进一步排查错误?

这些是旧邮件吗?这些邮件的日期是什么?

我的情况几乎一样。

POP3 一直正常工作了好几年,但从 2 月 23 日开始,邮件不再到达。

我检查了邮件服务器,Discourse 确实每隔几分钟就会轮询服务器,但什么也没收到。

邮件仍然停留在邮件服务器上。

注意:我在 2 月 22 日更新到了版本 2.7.0.beta4,因此我认为这很可能与此有关……

卡在邮件服务器中的邮件日期均在 POP3 停止工作之后,即在我这里是在 2 月 23 日之后。

好的,试试这个方法:

进入邮件服务器,删除其中的所有邮件。当然,需要有一种方法来保留你想保留的邮件……

然后等待 Discourse 再次通过 POP3 获取邮件。

现在这对我有效了,邮件又开始正常显示了。

我怀疑在最近的版本更新中,某个内部邮件 ID 计数器出错了。@codinghorror 也许它被设置成了一个非常大的数字,导致所有邮件都被当作“已读”之类的……

如果我不删除所有现有邮件,新邮件就会不断堆积。

POP3 轮询的最新变更发生在今年 1 月。

仅凭这一点不应阻止 Discourse 进行轮询,但传入的邮件可能会引发异常。新代码中没有任何错误处理机制……

@jzedlitz 您是否仍遇到该问题并希望协助彻底排查?在 /logs 中是否发现相关错误?在 /sidekiq/scheduler 中搜索 Jobs::PollMailbox 时是否看到错误?在 Rails 控制台中手动执行轮询时是否出现错误?

./launcher enter app
rails c

Jobs::PollMailbox.new.execute({})

通常,至少对我来说,情况是 POP3 轮询“成功”了。

我可以看到 Discourse 正在从邮件服务器轮询。

然而,Discourse 只是断开了连接,没有下载任何邮件。

至少对我来说,没有任何错误。

我们不久前还添加了一项安全检查,用于忽略非常旧的邮件,也许 @martin 还记得。

是的,这就是 @gerhardPOP3 email polling stopped working - #6 by gerhard 中链接的 PR。我想这应该不会破坏任何东西。我需要完整的原始邮件消息来进行测试。这是主要的代码变更:

def mail_too_old?(mail_string)
  mail = Mail.new(mail_string)
  date_header = mail.header['Date']
  return false if date_header.blank?

  date = Time.parse(date_header.to_s)
  date < 1.week.ago
end

所以我想,如果 Time.parse 失败,可能会存在一个静默错误?因为如果缺少 Date 头,我们甚至不会尝试执行任何操作。

抱歉未能及时回复。我们已通过清空 Discourse 的 POP3 邮箱,大致解决了该问题。清空后,Discourse 立即恢复了邮件抓取功能。我将一些较新的邮件移入已清空的 POP3 邮箱,这些邮件也能正常处理。然而,一旦我将部分 1,400 封旧邮件放入邮箱,Discourse 就无法再处理任何邮件了。

我刚刚也遇到了同样的问题。我注意到当邮件本应生成消息时,有些不对劲。POP3 邮箱里确实有几封邮件(我运行的是一个小型实例)。
逐条添加消息似乎解决了问题,我认为现在情况有所改善,但我还需要等待一段时间来确认。

很遗憾,问题再次出现。我使用 formail 将 mbox 拆分为单条邮件,并逐条导入到 POP3 账户中。部分(甚至是较旧的)邮件已被 Discourse 处理,但其他邮件未被处理。

是否有办法触发 Jobs::PollMailbox.new.execute({}) 输出更多日志信息,以查看为何某些邮件被忽略?

当发现无法处理的邮件时,您是否检查过 /logs

上面的帖子确实听起来像是特定消息在处理时失败了。

具体是哪个日志文件?我尝试了 tail -f /var/discourse/shared/standalone/log/rails/*.log,但在 Discourse 尝试获取邮件时没有任何消息显示。

作为管理员,请在您的浏览器中访问 https://discourse.example.com/logs。

值得注意的是,该文件夹名为 /log/,这并不是我所指的内容 :smirk:

感谢解释。遗憾的是,在获取邮件时 /logs/ 目录保持为空。是否有办法提高日志级别?

那么,POP3 轮询中的错误处理可能存在问题。需要有人检查代码,看看它是否在吞没错误。

能否在 Rails 控制台中运行 Jobs::PollMailbox.new.execute({}) 之前,在 Docker 容器内对 app/jobs/scheduled/poll_mailbox.rb 应用以下更改?

       pop3.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
+        mail_string = nil
         pop.each_mail do |p|
+          mail_string = nil
           mail_string = p.pop
           break if mail_too_old?(mail_string)
           process_popmail(mail_string)
           p.delete if SiteSetting.pop3_polling_delete_from_server?
+        rescue => e
+          puts e.message
+          puts e.backtrace.join("\n\t")
+          puts "", "MESSAGE:", mail_string if mail_string
         end
       end

既然我已经知道要查看哪个文件,我自己也进行了一些实验。问题出在 mail_too_old 检查上。在我移除它之后,卡住的消息就被处理了。

是的,我也有所怀疑,但了解具体是哪封邮件导致 mail_too_old? 无法工作会很有趣。那封邮件真的太旧了吗?是解析邮件时失败了吗?还是其他原因?如果你愿意,可以通过私信把那封导致 POP3 无法工作的邮件发给我。