简体   繁体   English

使Rails,Heroku,Unicorn,Sidekiq和Hirefire都玩起来不错

[英]Making Rails, Heroku, Unicorn, Sidekiq and Hirefire all play nice

We have a pretty complex Rails setup on Heroku. 我们在Heroku上有一个非常复杂的Rails设置。

In a typical day we have about 10 Web Dynos with Unicorn (each 2x and running 3 Unicorn workers) and 15 Worker Dynos running Delayed Jobs, though it fluctuates, so we use hirefire to scale up and down when we can to save on cost. 在典型的一天中,我们有大约10个Web dynos与Unicorn(每个2x并运行3个Unicorn工人)和15个Dynos运行“延迟作业”,尽管它波动,所以当可以节省成本时,我们使用hirefire来扩大和缩小规模。 Our Postgres database allows for 400 connections. 我们的Postgres数据库允许400个连接。

Last week I finally got fed up with our Delayed::Jobs queue that we had been using for several years; 上周,我终于对我们已经使用了几年的Delayed :: Jobs队列感到厌烦。 we have a series of jobs that were running every 10 minutes, it got to the point where it was taking more than 10 minutes to run all the jobs, so they queue would get backed up. 我们有一系列的作业每10分钟运行一次,直到运行所有作业都花费超过10分钟的时间,这样他们的队列才会得到备份。 I decided to make the decision to move over to Sidekiq, as I had had some success with it in the past. 我决定做出移居到Sidekiq的决定,因为我过去在此方面取得了一些成功。

It is working decently well so far, though I am finding our web dynos to be way less consistent. 到目前为止,它的运行情况还不错,尽管我发现我们的网络测功机不太稳定。 For example, here is our new relic graph of a 3 hour period yesterday: 例如,这是昨天昨天3小时的新遗物图:

新newrelic图

But here's what the exact same time period looked like the week before: 但是,这恰好是前一周的相同时间段:

旧的新文物图

Basically, before Sidekiq, our jobs didn't seem to be affecting our web dynos at all, but now they are. 基本上,在Sidekiq之前,我们的工作似乎根本没有影响到我们的网络测功机,但现在它们已经开始了。 My only guess here is that when our every 10 minute jobs run they are temporarily overwhelming our postgres connections, which is slowing down the web dynos. 我唯一的猜测是,每运行10分钟,它们就会暂时压倒我们的postgres连接,这会减慢网络测功的速度。 It's the only way I can imagine the jobs would effect the web. 这是我可以想象工作会影响网络的唯一方法。

Any thoughts on how to keep these a bit more separate, or so they are affecting each other less, and our web response time more consistent? 是否有关于如何将它们分开的想法,或者它们相互之间的影响较小,以及我们的Web响应时间更一致?

Here's our sidekiq.yml: 这是我们的sidekiq.yml:

---
:concurrency: 5
production:
  :concurrency: <%= ENV['WORKER_POOL'] || 15 %>
:queues:
  - [instant, 3]
  - [fetchers, 2]
  - [mailers, 1]
  - [fetch_all, 1]
  - [moderation, 1]
  - [default, 1]
  - [reports, 1]
  - [images, 1]
  - [slack, 1]

And our sidekiq.rb 还有我们的sidekiq.rb

require 'sidekiq'

Sidekiq.configure_server do |config|
  database_url = ENV['DATABASE_URL']
  if database_url
    pool = ENV['WORKER_POOL'] || 15
    new_database_url = "#{database_url}?pool=#{pool}"
    ActiveRecord::Base.establish_connection(new_database_url)
  end
end

Sidekiq.default_worker_options = { retry: 1 }

We are overwriting the pool setting on the db for the sidekiq worker instances so we can take full advantage of the concurrency. 我们将为sidekiq worker实例覆盖数据库上的池设置,以便我们可以充分利用并发性。

And our database.yml 还有我们的database.yml

production:
  database: myapp_production
  adapter: postgresql
  encoding: unicode
  pool: 5

And our unicorn.rb 还有我们的unicorn.rb

worker_processes 3
timeout 30
preload_app true
listen ENV['PORT'], backlog: Integer(ENV['UNICORN_BACKLOG'] || 200)

before_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

And our Procfile: 和我们的Procfile:

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
redis: redis-server
worker: bundle exec sidekiq -e production -C config/sidekiq.yml

Our hirefire managers are set up like 我们的聘用经理的设置如下

Web: 网页:

在此处输入图片说明

Workers: 工作人员:

在此处输入图片说明

Any suggestions? 有什么建议么?

It remains to be seen, but a very promising fix seems to have been turning off prepared_statements for the sidekiq workers in my config/database.yml : 尚待观察,但一个非常有前途的修复程序似乎已在我的config/database.yml为sidekiq工作者关闭了prepare_statements:

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  prepared_statements: <%= !Sidekiq.server? %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM