2008-08-02 26 views
18

Mam witrynę Ruby on Rails, która wykonuje połączenia HTTP z zewnętrzną usługą sieci Web.Częste SystemExit w Ruby podczas wykonywania połączeń HTTP

Raz dziennie otrzymuję komunikat o błędzie SystemExit (stacktrace below), w którym nie powiodło się wywołanie usługi. Jeśli później spróbuję dokładnie tego samego zapytania na mojej stronie, to działa dobrze. To się dzieje, odkąd strona została uruchomiona i nie miałem szczęścia, by znaleźć przyczynę.

Ruby to wersja 1.8.6, a szyny to wersja 1.2.6.

Ktoś jeszcze ma ten problem?

To jest błąd i stos śledzenia.

SystemExit nastąpiło /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/fcgi_handler.rb:116:in wyjścia” /usr/local/lib /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:in wywołanie' /usr/local/lib/ruby/1.8/net/protocol .rb: 133: w sysread ' /usr/local/lib/ruby/1.8/net/protocol.rb:133:in rbuf_fill' /usr/local/lib/ruby/1.8/timeout.rb:56:in timeout ' /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: w ciągu odczytu do " /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: w żądaniu " /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 "

Odpowiedz

8

Używanie fcgi z Rubinem jest bardzo błędne.

Praktycznie wszyscy przenieśli się do Mongrel z tego powodu, a ja polecam zrobić to samo.

8

Minęło trochę czasu odkąd użyłem FCGI, ale myślę, że proces FCGI mógł rzucić SystemExit, jeśli wątek trwa zbyt długo. Może to być usługa internetowa, która nie odpowiada lub nawet powolne zapytanie DNS. Niektóre wyniki google pokazują podobny błąd w Pythonie i FCGI, więc przejście na kundla byłoby dobrym pomysłem. This post jest moim punktem odniesienia, który użyłem do ustawienia kundla i nadal go wracam.

1

Chciałbym również rzucić okiem na Passenger. O wiele łatwiej jest zacząć od tradycyjnego rozwiązania Apache/nginx + Mongrel.

5

Zwykle korzystałem z nich cały czas na Apache1/fastcgi. Myślę, że jest to spowodowane zawieszaniem się fastcgi przed zakończeniem Ruby.

Przełączenie na kundla to dobry pierwszy krok, ale można zrobić jeszcze więcej. To zły pomysł, aby wyłapać z serwisów internetowych na żywo, szczególnie z Rails. Railsy nie są wątkowo bezpieczne. Liczba współbieżnych połączeń, które można obsłużyć, jest równa liczbie kundli (lub procesów pasażera) w klastrze.

Jeśli masz jednego kundla i ktoś uzyskuje dostęp do strony, która wywołuje usługę internetową, która trwa 10 sekund, wszystkie żądania do Twojej witryny zostaną przekroczone w tym czasie. Większość systemów równoważenia obciążenia po prostu ślizga się po twoich kundlach na ślepo, więc jeśli masz dwa kundle, każde inne żądanie upłynie.

Wszystko, co może być nieprzewidywalnie wolne, musi się wydarzyć w kolejce zadań. Pierwsze trafienie do/spowolnienie/akcja dodaje zadanie do kolejki, a/slow/akcja kontynuuje odświeżanie poprzez odświeżanie strony lub zapytania przez ajax aż do zakończenia zadania, a następnie otrzymasz wyniki z kolejki zadań. Obecnie istnieje kilka kolejek roboczych dla Railsów, ale najstarszym i prawdopodobnie najszerzej stosowanym jest BackgroundRB.

Inną alternatywą, w zależności od rodzaju aplikacji, jest wyodrębnianie usługi co N minut za pośrednictwem crona, buforowanie danych lokalnie i odczytywanie strony na żywo z pamięci podręcznej.