异步发送邮件时遇到“SSL_read: cert already in hash table”的错误。

39

使用ActionMailer异步发送延迟电子邮件时,我一直遇到一个OpenSSL::SSL::SSLError错误,错误信息是SSL_read: cert already in hash table

我们使用Sidekiq来异步发送所有电子邮件。当在Sidekiq GitHub仓库中提出此问题时,有人告诉我Sidekiq不知道或管理SSL连接。

我们的应用程序托管在Heroku上,其运行版本为OpenSSL 0.9.8k 25 Mar 2009

我们在其他作业中多次看到过这个错误,并发现有时会处理这些作业,但有时不会。

这是一个OpenSSL线程问题吗,多个Sidekiq线程正在尝试使用同一SSL连接?是否有解决方法?

以下是我们收到的堆栈跟踪:

    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/openssl/buffering.rb:175:in `sysread_nonblock`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/openssl/buffering.rb:175:in `read_nonblock`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/protocol.rb:153:in `rbuf_fill`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/protocol.rb:134:in `readuntil`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/protocol.rb:144:in `readline`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:932:in `recv_response`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:903:in `block in data`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:942:in `critical`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:896:in `data`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:663:in `block in send_message`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:852:in `rcptto_list`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:663:in `send_message`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/mail-2.5.4/lib/mail/network/delivery_methods/smtp.rb:113:in `block in deliver!`
    [PROJECT_ROOT]/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/smtp.rb:521:in `start`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/mail-2.5.4/lib/mail/network/delivery_methods/smtp.rb:112:in `deliver!`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/mail-2.5.4/lib/mail/message.rb:2129:in `do_delivery`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/mail-2.5.4/lib/mail/message.rb:232:in `block in deliver`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/actionmailer-4.0.3/lib/action_mailer/base.rb:456:in `block in deliver_mail`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.3/lib/active_support/notifications.rb:159:in `block in instrument`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.3/lib/active_support/notifications/instrumenter.rb:20:in `instrument`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.3/lib/active_support/notifications.rb:159:in `instrument`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/actionmailer-4.0.3/lib/action_mailer/base.rb:454:in `deliver_mail`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/mail-2.5.4/lib/mail/message.rb:232:in `deliver`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/extensions/action_mailer.rb:20:in `perform`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:49:in `block (3 levels) in process`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:122:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:122:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/newrelic_rpm-3.7.1.182/lib/new_relic/agent/instrumentation/sidekiq.rb:30:in `block in call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/newrelic_rpm-3.7.1.182/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:339:in `perform_action_with_newrelic_trace`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/newrelic_rpm-3.7.1.182/lib/new_relic/agent/instrumentation/sidekiq.rb:21:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-failures-0.3.0/lib/sidekiq/failures/middleware.rb:10:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-unique-jobs-2.7.0/lib/sidekiq-unique-jobs/middleware/server/unique_jobs.rb:15:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/active_record.rb:6:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/retry_jobs.rb:62:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/logging.rb:11:in `block in call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/logging.rb:22:in `with_context`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/server/logging.rb:7:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:124:in `block in invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:127:in `call`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/middleware/chain.rb:127:in `invoke`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:48:in `block (2 levels) in process`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:105:in `stats`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:47:in `block in process`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:86:in `do_defer`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/sidekiq-2.17.2/lib/sidekiq/processor.rb:37:in `process`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `public_send`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `dispatch`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:122:in `dispatch`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/actor.rb:322:in `block in handle_message`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/actor.rb:416:in `block in task`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/tasks.rb:55:in `block in initialize`
    [PROJECT_ROOT]/vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/tasks/task_fiber.rb:13:in `block in create

11
为什么 Heroku 运行的 OpenSSL 版本是 2009 年的?这太可怕了。 - tadman
3
看不到堆栈跟踪中的错误。跟踪是否完整? - Mircea
6
我刚刚运行了heroku run bash --remote production,然后运行了openssl version,看到的是OpenSSL 1.0.1f 6 Jan 2014。您是否考虑更新您的技术栈?https://devcenter.heroku.com/articles/stack - Dan Croak
3
由于这个问题已经两年没有任何活动,且提问者已经不见了,能否将其关闭或做些其他处理? - Sam
2
@AndyMikula,一个旧版本出现了问题,或者可能通过更新版本来解决,这本身不是一个有效的关闭理由。如果确实已知解决方案是更新堆栈,那么应该将其作为答案添加到问题中。人们经常使用旧的堆栈,因此这个答案仍然可以帮助某些人。988次浏览表明,这个问题要么吸引了人们寻找答案,要么曾经吸引了人们寻找答案。 - Wayne Conrad
显示剩余5条评论
1个回答

1

这与一个在2.3版本的补丁中修复的 Ruby并发问题有关。

您的日志显示您的应用程序正在运行2.0.0。将语言版本更新至至少稳定版本的2.3即可解决此问题。这可以通过更改您的Gemfile Ruby声明轻松完成:

ruby '2.3.8'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接