电子邮件停止发送 - 文件已到达末尾

大家好,如果这个帖子与之前提到类似错误的帖子相似,在此先致歉。

过去四天里,所有邮件发送都停止了,测试邮件也失败了。

我浏览了现有的类似主题,但在我的情况下,据我所知没有任何变更,邮件功能在之前数月一直正常运行的情况下突然失效。

我们使用 Digital Ocean 的托管服务,并配置了 G Suite SMTP 中继,用于从 droplet 的 IP 地址中继邮件。

Sidekiq 中列出的确切错误信息比 discourse-doctor 输出的要详细一些:

Jobs::HandledExceptionWrapper: Wrapped EOFError: end of file reached

discourse-doctor 仅显示:UNEXPECTED ERROR: end of file reached

我还确认可以通过以下方式连接到服务器:

telnet smtp-relay.gmail.com 587

我记得几个月前曾出现过一次短暂的邮件发送中断,但我不记得当时的错误信息了(当时我通过 Sidekiq 重试,没有任何问题)。

是否有人遇到过类似情况,或者拥有类似但仍正常运行的配置?提前感谢!

2 个赞

我还没有什么有用的建议,但遇到了完全相同的问题,环境也完全一致:DigitalOcean Droplet,通过 smtp-relay.gmail.com 发送邮件,出现 EOFErrors。

Sidekiq 报告如下错误:

Jobs::HandledExceptionWrapper: Wrapped EOFError: end of file reached

查看 /logs 目录,我得到了失败的堆栈跟踪,但没有任何明显有用的信息。

信息:

Job exception: end of file reached

堆栈跟踪:

/usr/local/lib/ruby/2.7.0/net/protocol.rb:225:in `rbuf_fill'
/usr/local/lib/ruby/2.7.0/net/protocol.rb:191:in `readuntil'
/usr/local/lib/ruby/2.7.0/net/protocol.rb:201:in `readline'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:944:in `recv_response'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:929:in `block in getok'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:954:in `critical'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:927:in `getok'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:826:in `helo'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:600:in `do_helo'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:554:in `do_start'
/usr/local/lib/ruby/2.7.0/net/smtp.rb:518:in `start'
mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:109:in `start_smtp_session'
mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:100:in `deliver!'
mail-2.7.1/lib/mail/message.rb:2159:in `do_delivery'
mail-2.7.1/lib/mail/message.rb:260:in `block in deliver'
actionmailer-6.0.3.3/lib/action_mailer/base.rb:589:in `block in deliver_mail'
activesupport-6.0.3.3/lib/active_support/notifications.rb:180:in `block in instrument'
activesupport-6.0.3.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport-6.0.3.3/lib/active_support/notifications.rb:180:in `instrument'
actionmailer-6.0.3.3/lib/action_mailer/base.rb:587:in `deliver_mail'
mail-2.7.1/lib/mail/message.rb:260:in `deliver'
actionmailer-6.0.3.3/lib/action_mailer/message_delivery.rb:115:in `block in deliver_now'
actionmailer-6.0.3.3/lib/action_mailer/rescuable.rb:17:in `handle_exceptions'
actionmailer-6.0.3.3/lib/action_mailer/message_delivery.rb:114:in `deliver_now'
/var/www/discourse/lib/email/sender.rb:234:in `send'
/var/www/discourse/app/jobs/regular/user_email.rb:70:in `send_user_email'
/var/www/discourse/app/jobs/regular/user_email.rb:25:in `execute'
/var/www/discourse/app/jobs/base.rb:232:in `block (2 levels) in perform'
rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:76:in `with_connection'
/var/www/discourse/app/jobs/base.rb:221:in `block in perform'
/var/www/discourse/app/jobs/base.rb:217:in `each'
/var/www/discourse/app/jobs/base.rb:217:in `perform'
sidekiq-6.1.2/lib/sidekiq/processor.rb:196:in `execute_job'
sidekiq-6.1.2/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'
sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:138:in `call'
sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:143:in `invoke'
sidekiq-6.1.2/lib/sidekiq/processor.rb:163:in `block in process'
sidekiq-6.1.2/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/job_retry.rb:111:in `local'
sidekiq-6.1.2/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq.rb:38:in `block in <module:Sidekiq>'
sidekiq-6.1.2/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/processor.rb:257:in `stats'
sidekiq-6.1.2/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/job_logger.rb:13:in `call'
sidekiq-6.1.2/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/job_retry.rb:78:in `global'
sidekiq-6.1.2/lib/sidekiq/processor.rb:124:in `block in dispatch'
sidekiq-6.1.2/lib/sidekiq/logger.rb:10:in `with'
sidekiq-6.1.2/lib/sidekiq/job_logger.rb:33:in `prepare'
sidekiq-6.1.2/lib/sidekiq/processor.rb:123:in `dispatch'
sidekiq-6.1.2/lib/sidekiq/processor.rb:162:in `process'
sidekiq-6.1.2/lib/sidekiq/processor.rb:78:in `process_one'
sidekiq-6.1.2/lib/sidekiq/processor.rb:68:in `run'
sidekiq-6.1.2/lib/sidekiq/util.rb:15:in `watchdog'
sidekiq-6.1.2/lib/sidekiq/util.rb:24:in `block in safe_thread'

环境信息:

hostname	conversation-app
process_id	736
application_version	e6bbe9b5df4d86fe711aa8b1d886489d30875633
current_db	default
current_hostname	conversation.sevarg.net
job	Jobs::UserEmail
problem_db	default
time	12:42 pm
opts	
type	digest
user_id	30
current_site_id	default

discourse-doctor 的输出也类似:

==================== MAIL TEST ====================
For a robust test, get an address from http://www.mail-tester.com/
Or just send a test message to yourself.
Email address for mail test? ('n' to skip) [[my email]]: 
Sending mail to [my email]. . . 
Testing sending to [my email] using smtp-relay.gmail.com:587.
======================================== ERROR ========================================
                                    UNEXPECTED ERROR

end of file reached

====================================== SOLUTION =======================================
This is not a common error. No recommended solution exists!

Please report the exact error message above to https://meta.discourse.org/
(And a solution, if you find one!)
=======================================================================================

我也可以 telnet 到中继服务器的 587 端口(并且手动发送测试邮件——我已经十年没这么干过了……),而且我想不起来最近有什么改动会影响邮件功能。

目前我在新用户注册等方面完全无法进行,这确实是个问题,因为我还在用它处理博客评论。我在 Google 日志中也找不到任何特别有帮助的信息,现在我真的想不出继续排查的办法了。一切看起来配置都正确,但就是无法正常工作了。

3 个赞

好吧,知道我的设置并不罕见,且并非只有我一人遭遇这些麻烦,确实让人宽慰。好奇问一下,你的问题也是大约5天前开始的吗?也许是我们管道中某个通用组件进行了更新。

感谢分享详细信息和回溯日志。我的情况与你的非常相似,错误信息也完全一致。

我尚未尝试通过 telnet 手动发送邮件,但我怀疑应该能像对你那样成功。

我们目前也面临同样的困境,暂时只能手动激活新用户(幸好每天只有少数几位)。考虑到我并未更改 G Suite、DigitalOcean 或 Discourse 配置中的任何内容,在无法确定问题根源之前,我有些犹豫是否要贸然进行任何修改。:confused:

1 个赞

Sidekiq 中首次出现明显的失败激增是在 1 月 14 日,也就是……5 天前。在此之前,我遇到过一些与无效邮件等相关的随机失败,但没有任何指标急剧上升。

我尝试在 Google 管理控制台中重新配置中继设置,并调整了这些设置(包括那些本应完全开放的选项),但没有任何变化。我也尝试了不同的邮件发送端口,同样没有变化。

此外,据我所知,5 天前我并没有进行任何更改。:confused:

再次报告问题,DigitalOcean → smtp-relay.gmail.com

是否有人能轻松地从非 DigitalOcean 虚拟机(例如 GCE 或其他)进行测试?

我刚在 GCE 上启动了一个 Discourse 安装,使用了我的凭据,结果遇到了同样的错误(已配置中继仅依赖身份验证)。

======================================== 错误 ========================================
                                    意外错误

到达文件末尾

====================================== 解决方案 =======================================
这不是一个常见错误。目前没有推荐的解决方案!

请将上述确切的错误信息报告至 https://meta.discourse.org/
(如果你找到了解决方案,也请一并告知!)
=======================================================================================

尝试为中继设置基于 IP 的身份验证后,结果相同。因此,我认为这不是 DigitalOcean 特有的问题……

不幸的是,“Ruby/Rails 邮件问题排查”超出了我目前的技能范围……有什么建议吗?

有没有可能是 Gmail SMTP 的问题?

看起来是这样。我不知道如何排查问题,目前为止我的修复尝试也毫无进展。他们很可能更改了某些内容,Discourse 无法处理,而且当然也没有技术支持。

我之前在这些论坛上帮忙排查和解决问题时,运气一直不错。不知道为什么这次这么冷清。

这可能是 Gmail/G Suite SMTP 的问题,但 @Syonyk 提到他曾在自己的 Droplet 上通过 telnet 手动成功发送过邮件。

我对 G Suite 如何区分来自网站自动发送的流量与手动发送的消息还不够了解,但这似乎表明问题出在向 smtp-relay.gmail 发送邮件的服务端,而非中继本身。

顺便一提,我已在 G Suite 管理员设置中明确允许了该 Droplet 的 IP 地址,并且过去几个月(至今)我从未更改过任何服务中的设置。

唯一一次遇到类似情况时,问题仅持续了一天(或许两天——当时页面访问量不大,如果时间更长我可能都察觉不到),而且似乎很快自行恢复了。

如果没有来自 Discourse 的 SMTP 对话的良好追踪记录,我无法进一步排查问题——而且我也不知道如何获取这些追踪记录。

有没有办法确认我每月通过 Discourse 发送的邮件数量?如果我需要切换到其他 SMTP 中继,我需要知道大概的预算。这真的让人非常沮丧。

在您的实例的 /admin/email/sent 页面下,您应该能够查看已发送的邮件并估算使用情况。

1 个赞

嗯……

我在服务器上运行了 tcpdump 并执行了 discourse-doctor,在输出中发现了以下内容……

...
0x0030:  d10f f8e4 4548 4c4f 206c 6f63 616c 686f  ....EHLO.localho
	0x0040:  7374 0d0a                                st..
...
	0x0030:  de62 f0c3 3432 3120 342e 372e 3020 5472  .b..421.4.7.0.Tr
	0x0040:  7920 6167 6169 6e20 6c61 7465 722c 2063  y.again.later,.c
	0x0050:  6c6f 7369 6e67 2063 6f6e 6e65 6374 696f  losing.connectio
	0x0060:  6e2e 2028 4548 4c4f 2920 6a31 3673 6d34  n..(EHLO).j16sm4
	0x0070:  3831 3932 3976 736d 2e31 202d 2067 736d  81929vsm.1.-.gsm
	0x0080:  7470 0d0a                                tp..

重要的是,我可以通过 telnet 复现此故障。

root@conversation:~# telnet smtp-relay.gmail.com 587
Trying 74.125.137.28...
Connected to smtp-relay.gmail.com.
Escape character is '^]'.
220 smtp-relay.gmail.com ESMTP ls8sm507258pjb.6 - gsmtp
ehlo localhost.localdomain
421 4.7.0 Try again later, closing connection. (EHLO) ls8sm507258pjb.6 - gsmtp
Connection closed by foreign host.

如果我发送一个实际的域名,则会得到预期的响应。

root@conversation:~# telnet smtp-relay.gmail.com 587
Trying 74.125.137.28...
Connected to smtp-relay.gmail.com.
Escape character is '^]'.
220 smtp-relay.gmail.com ESMTP p10sm668563uaw.3 - gsmtp
ehlo conversation.sevarg.net
250-smtp-relay.gmail.com at your service, [64.227.96.27]
250-SIZE 157286400
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8

那么,现在的问题是:如何让 Discourse 在 EHLO 命令中发送正确的域名字符串?

我不确定这是否是唯一的问题,但追查下去看起来很有希望。

1 个赞

这太奇怪了。这东西怎么会突然冒出来的?我根本没做过任何更新。

这不是突然出现的,它一直如此。是 Google 更改了某些东西。

如果你正在使用镜像,discourse-doctor 会调用 /var/www/discourse/lib/tasks/emails.rake 中的测试。

我将:

Net::SMTP.start(smtp[:address], smtp[:port], 'localhost', smtp[:user_name], smtp[:password], smtp[:authentication])

更改为:

Net::SMTP.start(smtp[:address], smtp[:port], 'conversation.sevarg.net', smtp[:user_name], smtp[:password], smtp[:authentication])

现在我得到了一个不同的错误。

======================================== 错误 ========================================
                                    意外错误

503 5.5.1 bad sequence of commands e190sm562849qkd.9 - gsmtp


====================================== 解决方案 =======================================
这不是一个常见错误。目前没有推荐的解决方案!

请将确切的错误信息报告至 https://meta.discourse.org/
(如果你找到了解决方案,也请一并提交!)
=======================================================================================

但是:重要的是,tcpdump 显示的数据流看起来还算正常(至少部分正常)。

22:33:48.393862 IP 64.227.96.27.54610 > 74.125.137.28.587: Flags [P.], seq 1:31, ack 59, win 502, options [nop,nop,TS val 3732187266 ecr 3508646052], length 30
	0x0000:  4500 0052 d4d6 4000 3f06 f237 40e3 601b  E..R..@.?..7@.`.
	0x0010:  4a7d 891c d552 024b 01b4 04a4 94ce dcc7  J}...R.K........
	0x0020:  8018 01f6 74dc 0000 0101 080a de74 a882  ....t........t..
	0x0030:  d121 b0a4 4548 4c4f 2063 6f6e 7665 7273  .!..EHLO.convers
	0x0040:  6174 696f 6e2e 7365 7661 7267 2e6e 6574  ation.sevarg.net
	0x0050:  0d0a                                     ..
22:33:48.408832 IP 74.125.137.28.587 > 64.227.96.27.54610: Flags [.], ack 31, win 256, options [nop,nop,TS val 3508646067 ecr 3732187266], length 0
	0x0000:  4500 0034 5e5d 0000 2b06 bccf 4a7d 891c  E..4^]..+...J}..
	0x0010:  40e3 601b 024b d552 94ce dcc7 01b4 04c2  @.`..K.R........
	0x0020:  8010 0100 a8ae 0000 0101 080a d121 b0b3  .............!..
	0x0030:  de74 a882                                .t..
22:33:48.469560 IP 74.125.137.28.587 > 64.227.96.27.54610: Flags [P.], seq 59:234, ack 31, win 256, options [nop,nop,TS val 3508646128 ecr 3732187266], length 175
	0x0000:  4500 00e3 5e8a 0000 2b06 bbf3 4a7d 891c  E...^...+...J}..
	0x0010:  40e3 601b 024b d552 94ce dcc7 01b4 04c2  @.`..K.R........
	0x0020:  8018 0100 929f 0000 0101 080a d121 b0f0  .............!..
	0x0030:  de74 a882 3235 302d 736d 7470 2d72 656c  .t..250-smtp-rel
	0x0040:  6179 2e67 6d61 696c 2e63 6f6d 2061 7420  ay.gmail.com.at.
	0x0050:  796f 7572 2073 6572 7669 6365 2c20 5b36  your.service,.[6
	0x0060:  342e 3232 372e 3936 2e32 375d 0d0a 3235  4.227.96.27]..25
	0x0070:  302d 5349 5a45 2031 3537 3238 3634 3030  0-SIZE.157286400
	0x0080:  0d0a 3235 302d 3842 4954 4d49 4d45 0d0a  ..250-8BITMIME..
	0x0090:  3235 302d 5354 4152 5454 4c53 0d0a 3235  250-STARTTLS..25
	0x00a0:  302d 454e 4841 4e43 4544 5354 4154 5553  0-ENHANCEDSTATUS
	0x00b0:  434f 4445 530d 0a32 3530 2d50 4950 454c  CODES..250-PIPEL
	0x00c0:  494e 494e 470d 0a32 3530 2d43 4855 4e4b  INING..250-CHUNK
	0x00d0:  494e 470d 0a32 3530 2053 4d54 5055 5446  ING..250.SMTPUTF
	0x00e0:  380d 0a                                  8..

因此,至少可以肯定,发送 “EHLO localhost” 或 “EHLO localhost.localdomain” 是问题的一部分。

那么,究竟该如何向实际开发人员报告这个 P0 级严重问题呢?

我肯定在论坛上见过这些人。据我所知,他们密切监控着这些论坛。我想说的是 GitHub,但该仓库的问题追踪功能似乎已禁用。

好的。

这是一封来自
https://conversation.sevarg.net
的测试邮件

电子邮件投递非常复杂。以下是你首先应该检查的几个重要事项:

我刚刚演示了一个修复方法,但我不知道如何将其贡献给上游项目。

cd /var/discourse
./launcher enter app
vim ./vendor/bundle/ruby/2.7.0/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb

你需要找到以下部分:

    DEFAULTS = {
      :address              => 'localhost',
      :port                 => 25,
      :domain               => 'localhost.localdomain',
      :user_name            => nil,
      :password             => nil,
      :authentication       => nil,
      :enable_starttls      => nil,
      :enable_starttls_auto => true,
      :openssl_verify_mode  => nil,
      :ssl                  => nil,
      :tls                  => nil,
      :open_timeout         => nil,
      :read_timeout         => nil
    }

修改 domain 相关的行。

    DEFAULTS = {
      :address              => 'conversation.sevarg.net',
      :port                 => 25,
      :domain               => 'conversation.sevarg.net',
      :user_name            => nil,
      :password             => nil,
      :authentication       => nil,
      :enable_starttls      => nil,
      :enable_starttls_auto => true,
      :openssl_verify_mode  => nil,
      :ssl                  => nil,
      :tls                  => nil,
      :open_timeout         => nil,
      :read_timeout         => nil
    }

我不确定哪一项关键,但修改这两项解决了问题。显然请使用你自己的域名……

退出应用环境。

./launcher restart app

现在应该能够发送邮件了。

我预计任何升级都会覆盖此修改。

不过,我现在已经可以按预期发送和接收邮件了。

开发者们?请尽快修复?

4 个赞

从我提交的错误报告中,请尝试以下操作:

添加

DISCOURSE_SMTP_DOMAIN: [您的安装域名]

到您的 app.yml 文件(很可能是 /var/discourse/containers/app.yml)

然后重新构建应用(cd /var/discourse; ./launcher rebuild app)并尝试发送邮件。

2 个赞

为明确起见,DISCOURSE_SMTP_DOMAIN 是指我的 Discourse 服务器域名,还是电子邮件的域名?

例如,我的服务器位于子域名 community.acescentral.com,而我的邮件来自 admin@acescentral.com。那么 DISCOURSE_SMTP_DOMAIN 是指顶层域名 acescentral.com,还是子域名 community

非常感谢您像猎犬一样锲而不舍地追查此问题。