Параллельные соединения с базой данных Приложение Heroku Unicorn rails

Я запускаю приложение rails на Heroku.

У меня есть один дино. Я использую базу данных Hobby Basic за 9 долларов в месяц с ограничением на 20 подключений.

Мое приложение работает на Unicorn. Но это все еще очень медленно, когда выполняется несколько вызовов базы данных.

Вот что у меня есть в моем файле unicorn.rb:

# config/unicorn.rb
worker_processes 3
timeout 30
preload_app true

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

В этой статье рассказывается об управлении одновременными подключениями: https://devcenter.heroku.com/articles/concurrency-and-database-connections

Но я все еще в замешательстве. Как с моей текущей настройкой разрешить одновременное подключение к нескольким базам данных? И при максимальном количестве подключений, которые позволяет моя база данных (20)? Я был бы очень признателен, если бы кто-то, кто имел дело с масштабированием приложения rails на Heroku, мог указать мне правильное направление.


person Katie H    schedule 08.04.2014    source источник
comment
Мне кажется, вам нужен один рабочий Unicorn для каждого соединения с базой данных. Каждый рабочий имеет одно соединение. Конечно, я никогда не использовал единорога, просто это выглядит из-за использования fork.   -  person Craig Ringer    schedule 08.04.2014


Ответы (2)


Справедливо предположить, что база данных может быть узким местом, когда вы используете ограниченный план хобби. Вероятно, есть некоторые оптимизации, которые вы можете сделать, чтобы помочь улучшить пул соединений независимо (например, код ниже). Однако, когда это действительно узкое место, вы ожидаете, что тайм-ауты происходят часто, а не только медлительность. Чтобы лучше понять, в чем заключаются ваши проблемы, я рекомендую добавить плагин NewRelic.

План NewRelic Stark (рекомендуется) или план Wayne (слишком ограниченный, на мой взгляд) бесплатны и помогут визуализировать производительность приложений и отследить ошибки. Скорее всего, вы обнаружите, что время ожидания в очереди динамометра и потребление памяти способствуют замедлению, которое вы получаете, и есть несколько способов улучшить это, даже не связываясь с соединениями с базой данных. Улучшение времени отклика вашего кода и ограничение обращений к базе данных (с помощью кэширования) — хорошие области для изучения.

С учетом сказанного я рекомендую добавить следующий код в ваш файл единорога, как описано в упомянутой вами статье.

after_fork do |server, worker|

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

  # other settings
  if defined?(ActiveRecord::Base)
    config = ActiveRecord::Base.configurations[Rails.env] ||
            Rails.application.config.database_configuration[Rails.env]
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    config['pool']            =   ENV['DB_POOL'] || 2
    ActiveRecord::Base.establish_connection(config)
  end
end
person blotto    schedule 13.04.2014
comment
В какую часть файла я бы это поместил? В конце? - person Katie H; 15.04.2014
comment
да, просто добавьте в конец файла после блока before_fork - person blotto; 15.04.2014
comment
Извините, мне было непонятно, заменить текущий блок after_fork или поместить его под текущий блок after_fork? - person Katie H; 15.04.2014
comment
ах нет, prb, я редактирую блок кода, чтобы вы могли использовать его полностью, и заменяю ваш старый - person blotto; 15.04.2014
comment
Спасибо большое! :)) - person Katie H; 15.04.2014

Heroku предоставляет управляемые базы данных Postgres. Разные многоуровневые базы данных имеют разные лимиты подключений. Базы данных начального уровня «Dev» и «Basic» ограничены 20 подключениями.

и одно соединение требуется на рабочем месте. если у вас есть работники более 20, вы можете использовать пул соединений, такой как pgbouncer, для решения проблемы. если вы используете pgbouncer , вы должны использовать режим пула транзакций в своей среде, чтобы сервер можно было повторно использовать между работниками.

person digoal.zhou    schedule 11.04.2014