В нашем приложении Rails есть две среды, которые мы развертываем на серверах: промежуточная среда и производственная среда по умолчанию.
Файл staging.rb является копией production.rb из папки config / environment. Разница между этими двумя значениями равна true:
config.whiny_nils = true
Поскольку приложение rails чаще всего используется для его API, мы запустили его на одном из наших внутренних промежуточных серверов, чтобы разработчики могли с ним работать. Это работало без сучка почти 4 месяца. Когда пришло время переносить на наш рабочий сервер, стек начал постоянно падать всякий раз, когда приходили POST или PUT с большим (иногда ОЧЕНЬ ОЧЕНЬ большим) телом. При тестировании между двумя серверами промежуточные серверы прекрасно обрабатывали одни и те же запросы.
Наиболее неприятной частью аварий / зависаний было отсутствие журналов или отслеживание места в стеке (nginx, phusion passenger, ruby 1.9 уровень патча 243, рельсы 2.3.4), где происходил сбой. Ничего не появилось в журнале ошибок nginx, журнале rails или в любом другом месте, которое мы могли бы найти. Так как мы работали на производственном сервере с обновленными версиями nginx, passenger и ruby (более высокий уровень исправления, чем промежуточная, но все еще 1.9), мы начали поочередно возвращать каждый компонент, вплоть до передачи всех исполняемых файлов и поддержки файлы (в основном все, что мы установили в / usr / local) на производственную машину безрезультатно. Когда мы собирались стереть машину и попробовать каждый шаг снова, кто-то предложил переключить производственную машину в «промежуточную» среду. , , и как магия, проблема решена!
Желая узнать, что могло вызвать ошибку, мы начали прочесывать ядро rails, наш собственный код и все наши плагины, пытаясь понять, что может вызвать такое массовое зависание / сбой в работе среда, опять же безрезультатно.
Единственной подсказкой, которую я смог найти, было поведение. При тестировании «на» приложении (одна из страниц, на которой фактически работает приложение rails), я бы аварийно завершил работу приложения, отправив запрос, а затем после частых обновлений (обычно 3-4) я мог бы выдать ошибку из Журнал Nginx и в конечном итоге приложение снова начнет обрабатывать запросы. Ошибка выглядит следующим образом:
Error during failsafe response: incompatible character encodings: UTF-8 and ASCII-8BIT
2009/10/09 17:52:40 [error] 8691#0: *88 upstream prematurely closed connection while reading response header from upstream, client: *my ip address*, server: myapp.mydomain.com, request: "GET /api/sections/4/edit HTTP/1.1", upstream: "passenger://unix:/tmp/passenger.8677/master/helper_server.sock:", host: "myapp.mydomain.com"
*** Exception NoMethodError in application (undefined method `each' for nil:NilClass) (process 8703): from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/rack/request_handler.rb:95:in `process_request'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_request_handler.rb:206:in `main_loop'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:376:in `start_request_handler'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:334:in `block in handle_spawn_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/utils.rb:182:in `safe_fork'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:332:in `handle_spawn_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:351:in `main_loop'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:195:in `start_synchronously'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:162:in `start'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/railz/application_spawner.rb:213:in `start'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:261:in `block (2 levels) in spawn_rails_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server_collection.rb:126:in `lookup_or_add'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:255:in `block in spawn_rails_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server_collection.rb:80:in `block in synchronize'
from :8:in `synchronize'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server_collection.rb:79:in `synchronize'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:254:in `spawn_rails_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:153:in `spawn_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/spawn_manager.rb:286:in `handle_spawn_application'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:351:in `main_loop'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/lib/phusion_passenger/abstract_server.rb:195:in `start_synchronously'
from /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.4/bin/passenger-spawn-server:61:in `'
Обычно, когда возникает ошибка кодировки символов, мой первый ход - ruby 1.9. , , однако, как вы можете заметить из моего тестирования, это была одна и та же версия на обеих машинах!
После всего этого, я думаю, мне интересно. , , Кто-нибудь есть какие-либо идеи, что происходит? Очевидно, что мы можем пока запустить наше приложение в стадии подготовки, но я волнуюсь, что, возможно, я нашел что-то более глубокое, что необходимо решить. Есть ли какие-нибудь идеи относительно следующего места, где я должен искать, где это происходит?
Наша установка:
Mac OS X Server: 10.6.1,
Рельсы 2.3.4,
Ruby 1.9p243,
Nginx 0.8.17,
Пассажир 2.2.5
Наши необходимые драгоценные камни:
environment.rb
Демоны
RMagick
test.rb
RSpec
RSpec рельсы
завод-девочка
рейк-тест
Наши установленные плагины:
actions-as-dag (плагин активной записи для создания ориентированных ациклических графов)
daemon_generator
globalize2
без подглядывания (для тестирования)
думающий сфинкс
ОБНОВЛЕНИЕ (в ответ на хеллл):
Я попытался добавить
config.whiny_nils = true
в производственной среде, однако сбой все еще происходит.
Кроме того, я вернулся на наш промежуточный сервер и установил для среды «Производство». , .Такой сбой!
Некоторые пояснения к тому, что я имел в виду под "большим" телом запроса. Один из методов POST / PUT, который постоянно приводил к аварийному завершению работы приложения, составлял приблизительно 20 000 символов (json). Поскольку API постоянно использовался в течение дня с небольшими PUTS / POSTS и оставался включенным, но падал / зависал только при выполнении этих более крупных запросов, я предположил, что они были подключены.
Что касается Rack / Ruby 1.9. Из-за большого количества информации о Rack и 1.9 я обновил наш Rack gem до последней версии в git-репозитории (которая предположительно исправила некоторые из проблем 1.9). Я читал о значительном количестве трудностей, связанных с rewindable_input, ruby 1.9 и более… однако, так как я не получал ошибку rewindable_input, с которой я столкнулся в моем другом приложении 1.9, я предположил, что это была другая проблема. Кроме того, я исключил Rack, когда изменение среды rails решило проблему (когда я искал в исходном коде Rack, казалось, что не было никаких специфических для среды методов, которые могли бы вызвать ошибку).
Надеюсь, это поможет!
ОБНОВЛЕНИЕ в ответ на pauliephonic
Нет сообщений, попадающих на логи рельсов вообще (что фактически подтолкнуло меня к поиску проблемы в нашем веб-стеке некоторое время). Моя подсказка о том, что происходит сбой / зависание, заключается в том, что после выполнения большого запроса приложение возвращает только 500 ошибок на каждый запрос, однако эти 500 ошибок не отображаются в журналах Rails.
Конфигурация нашей базы данных идентична (мы использовали кластер mysql, поэтому он был буквально идентичен, сейчас использует локальную базу данных mysql, но подтвердил, что ошибка завершается независимо от используемой базы данных)
Что касается нескольких байтов / юникод. , , мы работаем в интернационализированном приложении. , , однако я не думаю, что способ, которым рельсы обрабатывают изменения Unicode между производством и другими, не так ли? Как я уже говорил выше, это произошло POST
или PUT
. Во время отладки я проверял, как перейти к тем же страницам редактирования одной из моих больших, сильно вложенных моделей и просто попытаться "сохранить" ее. Это может привести к сбою приложения в рабочей среде, но не приведет к сбою приложения в процессе подготовки. Каждый раз, когда я тестировал одни и те же символы, один и тот же контент, одну и ту же кнопку, одинаковое поведение. , , другой ответ, основанный на окружающей среде. Я даже не мог перенаправить операторы puts
повсюду в моем коде, потому что (казалось, что) запросы не поступали в приложение rails. Я не получал сообщений об ошибках в моих журналах Rails или журналах ошибок Nginx (сохраните сообщение, которое я опубликовал при нескольких обновлениях).