2016-12-19 2 views
2

Rack Middleware и Heroku Request Queue иногда появляются в моем приложении Ruby/Sinatra, что заставляет приложение зависать, пока я не перезапустил сервер вручную. Я сделал хитрости для Rack :: Timeout, Postgres Timeout и обновил вызовы Postgres, чтобы они в основном работали до 100 мс. Как правило, когда очередь запросов увеличивается, серверы автоматически перезапускаются, а затем продолжаются без проблем, но когда возникает ошибка Middleware, приложение не может восстановиться, и приложение продолжает зависать в очереди запросов до тех пор, пока не истечет время ожидания. Что вызывает это?Что приводит к тому, что мое промежуточное ПО для стойки сканируется?

Вот скриншот из Нью-Relic показывая шип в Middleware:

New Relic chart showing time spent in Request Queuing increase to 20s, Middleware increase to 40s, and Ruby increase to 14s, then crashing. After that, time spent in Request Queue is always 20s

А вот файлы, в которых я устанавливаю промежуточного слоя и базы данных соединений:

конфигурации/puma.rb

threads_count = Integer(5) 
threads threads_count, threads_count 

preload_app! 

rackup  DefaultRackup 
port  ENV['PORT']  || 3000 
environment ENV['RACK_ENV'] || 'development' 

on_worker_boot do 
    ActiveSupport.on_load(:active_record) do 
     db = URI.parse(ENV['DATABASE_URL']) 
     ActiveRecord::Base.establish_connection(
      :adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme, 
      :host  => db.host, 
      :username => db.user, 
      :password => db.password, 
      :database => db.path[1..-1], 
      :port => db.port, 
      :encoding => 'utf8', 
      :reaping_frequency => 10 
      :pool => 5 
      :timeout => 11 
     ) 
    end 
end 

config.ru

require "rack-timeout" 
use Rack::Timeout, service_timeout: 16, wait_timeout: 23 

require './web' 

run Sinatra::Application 
use ActiveRecord::ConnectionAdapters::ConnectionManagement 

rakefile.rb

require "./web" 
require "sinatra/activerecord/rake" 

Gemfile

source 'https://rubygems.org' 
ruby '2.3.1' 
gem 'rack-timeout' 
gem 'rake' 
gem 'sinatra' 
gem 'puma', "~> 2.16.0" 
gem 'pg' 
gem "activerecord", "< 5.0.0" # h/t https://github.com/janko-m/sinatra-activerecord/pull/66 
gem 'activesupport' 
gem 'sinatra-activerecord' 
gem 'redis' 
gem 'tilt' 

Logfile от времени, когда приложение разбитого

app/web.2: Rack app error: #<Rack::Timeout::RequestTimeoutError: Request waited 783ms, then ran for longer than 15000ms> 
app/web.2: /app/vendor/bundle/ruby/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec' 
app/web.2: #<Rack::Timeout::RequestExpiryError: Request older than 30000ms.> 

Дополнительная Logfile с ошибкой, что иногда происходит перед приложением врезается

app/web.2: /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:187:in `lock', deadlock; recursive locking 
+0

FYI - когда я обновил свою базу данных до [standard-2] (https://devcenter.heroku.com/articles/heroku-postgres-plans), этот вопрос исчез. –

ответ

1

на основе этой линии трассировку ошибки тайм-аут:

/app/vendor/bundle/ruby/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec' 

Казалось бы, что в данный момент запроса был принудительно отключен (Rack :: Timeout), что активная запись находилась посреди этого вызова async_exec в вашей базе данных.

Основываясь на других ошибках у вас в курсе:

/app/vendor/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:187:in `lock', deadlock; recursive locking 

Я бы сказал, что это очевидно, что адаптер Postgres соединения столкнулся с мертвой точкой.

Неясно, происходит ли тупик в постгресах и пузырится до активной записи или если в коде адаптера подключен тупик. У вас есть медленные запросы, зарегистрированные в postgres? Ошибка взаимоблокировки может быть только symptom of using Rack::Timeout (or just the Timeout ruby class) while using threads. Возможно, что поток достиг тайм-аута из-за медленного запроса, вызвал тайм-аут :: Ошибка, а соединение/мьютекс в управлении соединением стало неустойчивым/несовместимым.

Смежные вопросы