Pergunta

Eu tenho um site Ruby on Rails que faz chamadas HTTP para um serviço Web externo.

Cerca de uma vez por dia recebo um e-mail de erro SystemExit (stacktrace abaixo) onde uma chamada para o serviço falhou.Se eu tentar exatamente a mesma consulta em meu site momentos depois, tudo funcionará bem.Isso vem acontecendo desde que o site foi ao ar e não tive sorte em descobrir o que causa isso.

Ruby é a versão 1.8.6 e Rails é a versão 1.2.6.

Alguém mais tem esse problema?

Este é o erro e o stacktrace.

Um SystemExit ocorreu /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/fcgi_handler.rb:116:in exit '/usr/local/lib/ruby/GEMS/1.8/gems/Ums/ Rails-1.2.6/lib/fcgi_handler.rb: 116: em exit_now_handler '/usr/local/lib/ruby/GEMS/1.8/GEMS/Activesuppport-1.4.4/lib/active_support/inflector.rb:250:in to_4 '/usr/local/lib/ruby/1.8/net/protocol.rb:133:in Call' /usr/local/lib/ruby/1.8/net/protocol.rb:133:in sysread '/usr/local/ lib/ruby/1.8/net/protocol.rb: 133: em rbuf_fill '/usr/local/lib/ruby/1.8/timeout.rb:56:in timeout' /usr/local/lib/ruby/1.8/timeout. RB: 76: no 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//local lib/ruby/1.8/net/http.rb: 2006: em read_new '/usr/local/lib/ruby/1.8/net/http.rb:1047:in request' /usr/local/lib/ruby/1.8/ net/http.rb: 945: em request_get '/usr/local/lib/ruby/1.8/net/http.rb:380:in get_ripson' /usr/local/lib/ruby/1.8/nets/http.rb: 543: In start '/usr/local/lib/ruby/1.8/net/http.rb:379:in get_restons'

Foi útil?

Solução

Usar fcgi com Ruby é conhecido por ser muito problemático.

Praticamente todo mundo mudou para vira-lata por esse motivo, e recomendo que você faça o mesmo.

Outras dicas

Já faz algum tempo que não uso o FCGI, mas acho que um processo FCGI poderia lançar um SystemExit se o thread demorasse muito.Pode ser que o serviço da web não esteja respondendo ou até mesmo uma consulta DNS lenta.Alguns resultados do Google mostram um erro semelhante com Python e FCGI, portanto, mudar para o mongrel seria uma boa ideia. Esta postagem é a minha referência que usei para configurar o mongrel e ainda me refiro a ela.

Eu costumava receber isso o tempo todo no Apache1/fastcgi.Acho que é causado pelo desligamento do fastcgi antes do Ruby terminar.

Mudar para o vira-lata é um bom primeiro passo, mas há mais a fazer.É uma má ideia extrair serviços da web em páginas ativas, principalmente do Rails.Rails não é seguro para threads.O número de conexões simultâneas que você pode suportar é igual ao número de vira-latas (ou processos de passageiros) em seu cluster.

Se você tiver um vira-lata e alguém acessar uma página que chama um serviço da Web que leva 10 segundos para atingir o tempo limite, todas as solicitações ao seu site atingirão o tempo limite durante esse período.A maioria dos balanceadores de carga apenas percorre seus vira-latas cegamente, portanto, se você tiver dois vira-latas, todas as outras solicitações atingirão o tempo limite.

Qualquer coisa que possa ser imprevisivelmente lenta precisa acontecer em uma fila de trabalhos.O primeiro hit em /slow/action adiciona o trabalho à fila e /slow/action continua atualizando por meio de atualizações de página ou consultas via ajax até que o trabalho seja concluído e então você obtém os resultados da fila de trabalhos.Existem algumas filas de jobs para Rails hoje em dia, mas a mais antiga e provavelmente a mais usada é AntecedentesRB.

Outra alternativa, dependendo da natureza do seu aplicativo, é selecionar o serviço a cada N minutos via cron, armazenar os dados em cache localmente e fazer com que sua página ativa seja lida no cache.

Eu também daria uma olhada Passageiro.É muito mais fácil de começar do que a solução tradicional do Apache/nginx + Mongrel.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top