Unicorn!и PostgreSQL - PullRequest
       4

Unicorn!и PostgreSQL

5 голосов
/ 25 ноября 2011

Я нахожусь в процессе обновления старого приложения Rails и PostgreSQL с 2.1 до Rails 3 (с помощью успешного промежуточного шага 2.3.11).

Наконец, когда я получил все Rspecs, работающие гладко, яустановил Mongrel 1.2.0.pre2 и запустил - все в порядке.Даже тестовый случай JMeter со 100 одновременными пользователями прошел нормально.

Но когда я попробовал то же самое с Unicorn!сервер, он отлично работает, когда я использую его сам, но когда я получаю его под нагрузкой с JMeter, он начинает выдавать 100% ошибок с того момента, когда JMeter пытается POST логин.В то же время, когда я проверяю какую-то конкретную страницу, она выдает мне странные ошибки, подобные этой:

undefined method `eq' for nil:NilClass

На терминале я получаю следующий вывод (но только несколько раз):

message type 0x43 arrived from server while idle
message type 0x5a arrived from server while idle
WARNING:  there is already a transaction in progress

РЕДАКТИРОВАТЬ: похоже, это проблема с общим PGconnect объектом, поэтому я удалил часть предыдущего текста

Я обнаружил, что Документы PostgreSQL указывают, чтоPGconn объект не должен быть разделен между потоками, выполняющими параллельные запросы.

Является Unicorn!или AR смешивая запросы из разных потоков в одном и том же PGconn объекте?

Database.yml:

production:
  adapter: postgresql
  encoding: unicode
  database: ***
  username: ***
  password: ***
  host: 127.0.0.1

Я даже пытался добавить это безрезультатно:

  allow_concurrency: true

unicorn.conf:

worker_processes 8
working_directory "/full/path/to/app"
listen '/tmp/app.sock', :backlog => 512
timeout 30
pid "/full/path/to/app/tmp/pids/puppetmaster_unicorn.pid"

preload_app true
  if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

Характеристики:

  • Rails 3.0.6 (из-за среды развертывания)
  • Unicorn!4.1.1
  • Nginx 1.0.5
  • pg gem 0.11.0
  • PostgreSQL 9.0.4
  • Mac OS X 10.7.2

Если виновником является версия Rails, конечно, я могу обновить ее до последней версии.Я только начал с того, что есть у поставщика услуг.

1 Ответ

7 голосов
/ 01 декабря 2011

Очень важно не делиться соединениями с базами данных между процессами. Когда вы запускаете Rails с preload_app, Rails установит соединение (я) AR, прежде чем мастер-единорог разветвляет рабочих. В примере unicorn.conf.rb есть рекомендация отключить соединение AR в ловушке before_fork. AR автоматически восстановит новое соединение, так как каждый работник требует его после форка.

выдержка из http://unicorn.bogomips.org/examples/unicorn.conf.rb:

before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
  # ...
end
...