2013-04-09 9 views
10

OS X 10.8.3Gniazdka nie wydają się być zamknięcie przy użyciu node.js http.get

Węzeł 0.10.0

używam „http” moduł do żądań Interfejs API wykresu Facebook.

Oto opcje, które mijam na „http.get”:

var options = {host: 'graph.facebook.com', 
       port: 80, 
       path: '/' + fb_id + '/picture'}; //fb_id is a Facebook user identifier 

Mój kod wygląda następująco:

http.get(options, 
    function(res) { 
    ...some stuff... 
    DONE(RESULT); //DONE is a callback function 
    }).on('error', function(e) { 
     ...some error handling... 
}); 

Co mogę obserwować to, że mogę zrobić tylko tyle żądań jako wartość http.globalAgent.maxSockets. Po osiągnięciu wielu żądań, następne wywołanie http.get nigdy (pozornie) się nie łączy. Weryfikowałem, że nie dostaję błędów w żądaniach.

To tak jakby gniazda nie są zamykane po odpowiedź przychodzi.

Czy jest coś, co muszę zrobić w ramach obsługi reagowania w celu zapewnienia, że ​​gniazdo jest zamknięty?

Czy te gniazda nie są zamykane z powodu domyślnego zachowania keepalive?

Jak mam przystąpić do debugowania tego?

Odpowiedz

7

Spróbuj ustawić agent: false w opcjach. Domyślne zachowanie jest rzeczywiście utrzymać połączenia otwarte dla HTTP keep-alive:

var options = {host: 'graph.facebook.com', 
       port: 80, 
       path: '/' + fb_id + '/picture', 
       agent: false}; 
+0

Widziałem to w dokumentacji, ale stwierdziłem, że jest mylące: "Jeśli oczekujące żądania HTTP nie czekają na gniazdo, aby się uwolnić, gniazdo zostanie zamknięte.Oznacza to, że pula węzła ma tę zaletę, że utrzymuje się przy obciążeniu, ale nadal nie wymaga od programistów ręcznego zamykania klientów HTTP przy użyciu funkcji keep-alive. " Nie rozumiem, dlaczego połączone, już otwarte połączenia nie są użyty dla kolejnych żądań Spróbuję agent: false i oczekiwać od niego dobrych rzeczy –

+0

Myślę, że moduł 'http' nie kolejkuje żadnych żądań, dla których gniazdo nie jest dostępne w puli. jest osiągnięty, a wszystkie żądania oczekują, żadne kolejne żądania nie mogą uzyskać bezpłatnego gniazda z puli i zostaną po prostu usunięte. – robertklep

+0

Zdałem sobie sprawę, że moja architektura aplikacji przyczyniła się do mojego problemu, ponieważ ponownie zażądałem Moduł "http" przed każdym żądaniem, co oznacza, że ​​każde odwołanie http było autonomiczne: Próbowałem zmienić to tak, aby ht Odwołanie do modułu tp zostało udostępnione w wywołaniach "get", ale widzę to samo zachowanie (pierwsze żądania globalAgent.maxSockets są w porządku, reszta zawiesza się z powodu braku gniazda). To nasuwa pytanie - jak można skorzystać z tego domyślnego zachowania keepalive? –

2

stany modułu http węzła, który domyślnie agenta do agenta globalnego: http://nodejs.org/api/http.html#http_http_globalagent, co oznacza, że ​​keep-alive jest wspólne, niezależnie od modułu, który początki żądanie.

BTW, odpowiadając na komentarz Wesa z kwi 9'13 o 20:47: nie ma znaczenia, ile razy ładujesz moduł węzła, zostanie on załadowany tylko raz i udostępniony przez wszystkie moduły.

Występuje problem z wyczerpaniem basenu. Najprostszym sposobem na uniknięcie tego jest użycie nowego agenta (http://nodejs.org/api/http.html#http_class_http_agent) z żądanymi maxSockets. Pamiętaj, że utworzony agent może być współdzielony między modułami, jeśli umieścisz go w eksporcie tego modułu (moduły w węźle są stanowe !!!).

2

Doświadczyłem tego samego zachowania, z tym że moje połączenia zostały w końcu ponownie wykorzystane po upływie limitu czasu. Sprawdź, czy połączenia są ponownie używane po pewnym czasie (kilka minut), a także sprawdź, czy nagłówki odpowiedzi zawierają "Połączenie: utrzymaj przy życiu".

Jeśli tak jest, rozwiązaniem byłoby użycie nagłówka "Połączenie: Zamknij" zamiast utrzymywania łączności, dzięki czemu połączenia zbiorcze mogłyby zostać ponownie użyte wcześniej, jak w zwykłej konfiguracji. Nie jestem pewien, czy prowadzi to do problemów z wydajnością za pomocą punktów końcowych na Facebooku.

var options = {host: 'graph.facebook.com', 
       port: 80, 
       path: '/' + fb_id + '/picture', 
       headers: { 'Connection':'Close' } 
}; 

Dla mnie przy użyciu agenta: fałsz nie działa, ponieważ ogromna liczba żądań wysłał wyczerpane zasoby serwera.

Powiązane problemy