2013-04-09 11 views
10

OS X 10.8.3Sockets non sembrano essere chiusura quando si utilizza Node.js http.get

Nodo 0.10.0

sto usando il 'http' modulo per effettuare richieste del API grafico Facebook.

Qui ci sono le opzioni che mi passano per 'http.get':

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

Il mio codice è simile al seguente:

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

quello che osservo è che posso solo fare il maggior numero di richieste come valore di http.globalAgent.maxSockets. Una volta raggiunte così tante richieste, la prossima chiamata a http.get mai (apparentemente) si connette. Ho verificato che non ricevo errori sulle richieste.

E 'come se le prese non vengono chiuse dopo la risposta arriva.

c'è qualcosa che devo fare come parte del gestore di risposta per garantire che il socket viene chiuso?

Queste prese non si chiudono a causa del comportamento keepalive predefinito?

Come devo procedere per eseguire il debug di questo?

risposta

7

Provare a impostare agent: false nelle opzioni. Il comportamento predefinito è infatti quello di mantenere le connessioni aperte per HTTP keep-alive:

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

Ho visto questo nella documentazione ma ho trovato confuso: "Se nessuna richiesta HTTP in attesa è in attesa su un socket per diventare libero il socket è chiuso.Ciò significa che il pool del nodo ha il vantaggio di keep-alive quando è sotto carico ma non richiede agli sviluppatori di chiudere manualmente i client HTTP usando keep-alive. " Non capisco perché le connessioni raggruppate, già aperte, non siano usato per le richieste successive. Proverò agente: falso, e mi aspetto cose positive da esso. –

+0

Penso che il modulo 'http' non accoda alcuna richiesta per la quale un socket non è disponibile nel pool. viene raggiunto e tutte quelle richieste sono ancora in attesa, eventuali richieste successive non possono ottenere un socket gratuito dal pool e verranno rilasciate. – robertklep

+0

Mi sono reso conto che la mia architettura dell'applicazione stava contribuendo al mio problema da quando richiedevo nuovamente il modulo "http" prima di ogni richiesta, il che significa che ogni riferimento http era autonomo Ho provato a cambiare questo in modo che il ht il riferimento del modulo tp è stato condiviso tra invocazioni 'get', ma vedo lo stesso comportamento (le prime richieste di globalAgent.maxSockets vanno bene, il resto è sospeso per mancanza di un socket). Questo pone la domanda: come si potrebbe approfittare di questo comportamento keepalive predefinito? –

2

del nodo del modulo http afferma che le inadempienze agente a agente globale: http://nodejs.org/api/http.html#http_http_globalagent, il che significa che keep-alive è condiviso indipendentemente dal modulo che origini le richiesta.

BTW, rispondendo al commento di Wes di Apr9'13 alle 20:47: non importa quante volte si carica un modulo nodo, verrà caricato solo una volta e condiviso da tutti i moduli.

Quello che stai vivendo è un problema di esaurimento della piscina. Il modo più semplice per evitarlo è utilizzare un nuovo agente (http://nodejs.org/api/http.html#http_class_http_agent) con i maxi socket desiderati. Ricorda che l'agente che crei può essere condiviso tra i moduli se lo inserisci in un'esportazione di quel modulo (i moduli nel nodo sono stateful !!!).

2

Ho riscontrato lo stesso comportamento, tranne che le mie connessioni sono state infine riutilizzate dopo un periodo di timeout. Controlla se le connessioni vengono riutilizzate dopo un certo periodo di tempo (un paio di minuti) e controlla anche se le intestazioni di risposta contengono "Connessione: keep-alive".

In questo caso, una possibile soluzione consiste nell'utilizzare l'intestazione 'Connection: Close' invece che keep-alive, in questo modo le connessioni in pool potrebbero essere riutilizzate prima come nel solito setup. Non sono sicuro che ciò porti a problemi di prestazioni con gli endpoint di Facebook.

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

Per me usando agente: true non ha funzionato a causa del gran numero di richieste che ha inviato le risorse del server esaurite.

Problemi correlati