Actual Result:
我们正在使用sidekiq web UI(使用sidekiq-failures gem)显示失败的邮件工作,这些工作在大约一分钟后成功重试 .
Failure Error:
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=234
Expected:
我们希望sidekiq工作人员能够立即成功并且不会失败,并且稍后会(尽管已成功)重试 .
设置:Heroku Cedar-14,Rails 4.2,Puma 2.11.2,Sidekiq 3.3.4,Sidekiq-failures 0.4.4
config/initializers/sidekiq.rb:
Sidekiq.configure_server do |config|
database_url = ENV['DATABASE_URL']
if database_url
ENV['DATABASE_URL'] = "#{database_url}?pool=15"
ActiveRecord::Base.establish_connection
end
end
config/puma.rb:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
ActiveRecord::Base.establish_connection
end
config/sidekiq.yml
---
:concurrency: 25
:queues:
- default
- mailers
- [low, 1]
- [med, 2]
- [high, 3]
电子邮件是从控制器操作中的服务运行触发的:
app/services/user_events.rb
@user = User.find(234)
UserMailer.send_email(@user.id).deliver_later
app/mailers/user_mailer.rb
def send_email(user_id)
@user = User.find(user_id)
# mandrill_headers
headers['X-MC-Track'] = "opens, clicks_all"
headers['X-MC-Tags'] = ['user-event']
mail(to: @user.email, subject: "Hi", css: ["email"])
end
2 回答
@user
是新创建的记录吗?如果是这样,我的预感是您在提交当前数据库事务之前将sidekiq电子邮件作业排入队列 .在这种情况下,新用户存在于Rails事务中,但是连接到数据库的其他进程尚未看到它,因为新用户记录尚未提交到数据库 . 当sidekiq运行电子邮件作业(它在与Rails应用程序不同的进程中运行)时,它会尝试加载用户并获取
RecordNotFound
.解决方案是将sidekiq作业排入数据库事务之外(之后) . 如果您正在使用ActiveRecord回调,那意味着您应该使用
after_commit
而不是after_create
.来自sidekiq FAQ:https://github.com/mperham/sidekiq/wiki/FAQ#why-am-i-seeing-a-lot-of-cant-find-modelname-with-id12345-errors-with-sidekiq
问题解决了 . 事实证明,heroku回滚还原了一个环境变量 .