2008-08-02 6 views
18

У меня есть сайт Ruby on Rails, который делает HTTP-вызовы внешним веб-сервисом.Частый SystemExit в Ruby при выполнении HTTP-звонков

Примерно раз в день я получаю сообщение об ошибке SystemExit (stacktrace ниже), в котором сбой вызова службы. Если я затем попытаюсь выполнить тот же самый запрос на моем сайте через несколько секунд, он отлично работает. Это происходит с тех пор, как сайт пошел вживую, и мне не удавалось отслеживать, что вызывает его.

Ruby - версия 1.8.6, а рельсы - версия 1.2.6.

У кого-нибудь еще есть эта проблема?

Это ошибка и stacktrace.

SystemExit произошло /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/fcgi_handler.rb:116:in выхода» /USR/местные/Библиотека /ruby/gems/1.8/gems/rails-1.2.6/lib/fcgi_handler.rb:116:in exit_now_handler ' /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib /active_support/inflector.rb:250:in to_proc '/usr/local/lib/ruby/1.8/net/protocol.rb:133:в вызове' /usr/local/lib/ruby/1.8/net/protocol .rb: 133: in sysread ' /usr/local/lib/ruby/1.8/net/protocol.rb:133:in rbuf_fill' /usr/local/lib/ruby/1.8/timeout.rb:56:in тайм-аут ' /usr/local/lib/ruby/1.8/timeout.rb:76:in timeout ' /usr/local/lib/ruby/1.8/net/protocol.rb:132:in rbuf_fill' /usr/local/lib/ruby ​​/ 1.8/net/protocol.rb: 116: in readuntil ' /usr/local/lib/ruby/1.8/net/protocol.rb:126:in readline' /usr/local/lib/ruby ​​/ 1.8/net/http.rb: 2017: in read_status_line ' /usr/local/lib/ruby/1.8/net/http.rb:2006:in read_new' /usr/local/lib/ruby/1.8/net/ http.rb: 1047: in request ' /usr/local/lib/ruby/1.8/net/http.rb:945:in request_get' /usr/local/lib/ruby/1.8/net/http.rb: 380: in get_response ' /usr/local/lib/ruby/1.8/net/http.rb:543:in start' /usr/local/lib/ruby/1.8/net/http.rb:379:in get_response '

ответ

8

Использование fcgi с Ruby, как известно, очень плохое.

По этой причине практически все переехали в Mongrel, и я рекомендую вам сделать то же самое.

8

Прошло некоторое время с тех пор, как я использовал FCGI, но я думаю, что процесс FCGI может вызывать SystemExit, если поток слишком длительный. Это может быть веб-сервис, не отвечающий или даже медленный DNS-запрос. Некоторые результаты Google показывают аналогичную ошибку с Python и FCGI, поэтому переключение на mongrel было бы хорошей идеей. This post - это моя ссылка, которую я использовал для настройки дворняжки, и я все еще обращаюсь к ней.

1

Я также посмотрю Passenger. Гораздо легче добиться успеха, чем традиционное решение Apache/nginx + Mongrel.

5

Я использовал их все время на Apache1/fastcgi. Я думаю, что это вызвано быстрым зависанием до того, как Руби закончится.

Переключение на mongrel - хороший первый шаг, но есть еще что делать. Плохая идея отбросить веб-сервисы на живые страницы, особенно от Rails. Рельсы не являются потокобезопасными. Количество одновременных подключений, которые вы можете поддерживать, равно числу mongrels (или пассажирских процессов) в вашем кластере.

Если у вас есть один mongrel, и кто-то обращается к странице, которая вызывает веб-службу, которая занимает 10 секунд до тайм-аута, каждый запрос на ваш веб-сайт будет тайм-аут в течение этого времени. Большинство балансиров нагрузки просто чередуются с вашими ублюдками вслепую, поэтому, если у вас есть две mogrels, каждый другой запрос будет тайм-аут.

Все, что может быть непредсказуемо медленным, должно произойти в очереди заданий. Первый удар в/slow/action добавляет задание в очередь, а/slow/action продолжает обновляться через обновления страницы или запросы через ajax до завершения задания, а затем вы получаете результаты из очереди заданий. В настоящее время существует несколько очередей заданий для Rails, но самый старый и, вероятно, наиболее широко используемый - BackgroundRB.

Другой альтернативой, в зависимости от характера вашего приложения, является отбраковка службы каждые N минут через cron, кеширование данных локально и чтение вашей живой страницы из кеша.

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