2016-06-12 11 views
7

Ho tra 1000-2000 pagine web da scaricare da un server, e sto usando routine e canali per ottenere un'alta efficienza. Il problema è che ogni volta che eseguo il mio programma fino a 400 richieste falliscono con l'errore "connessione ripristinata dal peer". Raramente (forse 1 su 10 volte), nessuna richiesta fallisce.Vai http.Get, concorrenza e "Connessione ripristinata dal peer"

Cosa posso fare per impedirlo?

Una cosa interessante è che quando ho eseguito questo programma su un server nello stesso paese del server in cui è ospitato il sito, 0 richieste non sono riuscite, quindi suppongo che ci sia qualche problema con il ritardo (dato che è ora in esecuzione su un server in un altro continente).

Il codice che sto usando è fondamentalmente solo una semplice richiesta http.Get (url), nessun parametro extra o un client personalizzato.

+0

Sono tutte o una gran parte delle pagine provenienti dallo stesso server? qual è il numero massimo di richieste che stai facendo contemporaneamente? – JimB

+0

Tutte le pagine provengono dallo stesso server (modificato la domanda per riflettere questo). Non sono sicuro di quanti ne vengano realizzati contemporaneamente. Ho appena iniziato tante routine di go quante sono le pagine web da scaricare e poi lascia che la CPU/Golang impongano i limiti della concorrenza. – fgblomqvist

+0

Non ci sono limiti definiti sulla concorrenza, è necessario farlo da soli. – JimB

risposta

11

Il messaggio connection reset by peer indica che il server remoto ha inviato un RST di chiudere con forza la connessione, deliberatamente come un meccanismo per limitare le connessioni, o come risultato di una mancanza di risorse. In ogni caso è probabile che si aprano troppe connessioni o si ricolleghi troppo velocemente.

L'avvio delle connessioni 1000-2000 in parallelo è raramente il modo più efficiente per scaricare molte pagine, soprattutto se la maggior parte o tutte provengono da un singolo server. Se verifichi il throughput, troverai un livello di concorrenza ottimale molto più basso.

Si desidera inoltre impostare Transport.MaxIdleConnsPerHost in modo che corrisponda al proprio livello di concorrenza. Se MaxIdleConnsPerHost è inferiore al numero previsto di connessioni simultanee, le connessioni al server saranno spesso chiuse dopo una richiesta, solo per essere immediatamente riaperte - questo rallenterà significativamente i tuoi progressi e probabilmente raggiungerà i limiti di connessione imposti dal server.

+1

Questa è un'ottima risposta. Ho finito per fare alcune misurazioni su quante connessioni simultanee hanno dato le migliori prestazioni, e per questa connessione sono attualmente attivo, che è risultato essere circa 50, più connessioni di quelle che hanno dato pochissime prestazioni extra. Ho limitato la quantità di routine di go in esecuzione a un massimo di 50 e ho impostato MaxIdleConnsPerHost su 50. Funziona ogni volta! – fgblomqvist

+0

@ AG1: quale codice stai cercando? La risposta si riduce alla semplice impostazione di 'MaxIdleConnsPerHost' per eguagliare il numero di richieste simultanee. – JimB

+0

@JimB Ho aggiunto il codice come risposta per renderlo più concreto. – AG1

1

Potrebbe essere possibile che il server da cui si scaricano le pagine Web abbia un qualche tipo di meccanismo di limitazione che impedisce più di un certo numero di richieste al secondo/(o simili) da un determinato IP ?. Prova a limitare fino a 100 richieste al secondo o ad aggiungere il sonno tra le richieste. La connessione ripristinata dal peer è fondamentalmente server che ti nega il servizio. (What does "connection reset by peer" mean?)

+0

Considerando che tutto funziona alla perfezione quando lo eseguo su un server nello stesso paese del server web, apparentemente non ha tali limiti (a meno che non siano imposti solo a persone di altri paesi, il che non ha molto senso il mio scenario). Tuttavia, cercherò di limitare la quantità di richieste al secondo. – fgblomqvist

+0

In genere i server possono gestire solo un determinato numero di richieste simultanee e la capacità potrebbe essere superata. Una ragione per cui potrebbe funzionare bene nello stesso paese è che la richiesta probabilmente impiegherebbe molto meno tempo, quindi la connessione non viene utilizzata tanto a lungo e il server può gestire di più. – robbrit

+0

@robbrit Suppongo che sia probabilmente il caso. Dovrò implementare un pool di connessioni, penso. – fgblomqvist

5

Ancora un principiante golang, speriamo che questo aiuti.

var netClient = &http.Client{} 

func init() { 
    tr := &http.Transport{ 
     MaxIdleConns:  20, 
     MaxIdleConnsPerHost: 20, 
    } 
    netClient = &http.Client{Transport: tr} 
} 

func foo() { 
    resp, err := netClient.Get("http://www.example.com/") 
} 
+1

Uno per codice effettivo che dimostra le soluzioni pubblicate qui – fgblomqvist

Problemi correlati