2012-05-23 5 views
47

Questo semplice server HTTP contiene una chiamata a time.Sleep() che rende ogni richiesta impiega cinque secondi. Quando provo a caricare rapidamente più schede in un browser, è ovvio che ogni richiesta viene accodata e gestita in modo sequenziale. Come posso far sì che gestisca richieste concorrenti?Perché il mio server web in golang non gestisce richieste concorrenti?

package main 

import (
    "fmt" 
    "net/http" 
    "time" 
) 

func serve(w http.ResponseWriter, r *http.Request) { 
    fmt.Fprintln(w, "Hello, world.") 
    time.Sleep(5 * time.Second) 
} 

func main() { 
    http.HandleFunc("/", serve) 
    http.ListenAndServe(":1234", nil) 
} 

In realtà, ho appena trovato la risposta a questo dopo aver scritto la domanda, ed è molto sottile. Lo sto pubblicando comunque, perché non ho trovato la risposta su Google. Riesci a vedere cosa sto facendo male?

+0

Qual è la risposta che hai trovato? –

+3

Il problema era nel modo in cui ho provato. I browser Web limitano il numero di connessioni che effettuano a qualsiasi server, anche tra le schede. –

+1

Potrebbe anche piacerti usare jMeter per inviare una richiesta al tuo server –

risposta

84

Il programma gestisce già le richieste contemporaneamente. È possibile verificare con ab, uno strumento di riferimento che viene fornito con Apache 2:

ab -c 500 -n 500 http://localhost:1234/ 

Sul mio sistema, il punto di riferimento prende un totale di 5043ms per servire tutte le 500 richieste simultanee. È solo il tuo browser che limita il numero di connessioni per sito web.

Benchmarking I programmi Go non sono così semplici, perché è necessario assicurarsi che lo strumento di benchmark non sia il collo di bottiglia e che sia anche in grado di gestire molte connessioni simultanee. Pertanto, è una buona idea utilizzare un paio di computer dedicati per generare carico.

+24

Voglio modificare la tua risposta per rimuovere la parola "Vai" da quell'ultimo paragrafo ... ;-) – Ashe

+1

Sto cercando di capire il codice: implichiamo che http. HandleFunc() genera una goroutine per gestire la richiesta e quindi restituisce immediatamente? – Eno

+9

Le goroutine vengono generate molto prima. http.ListenAndServe accetta nuove connessioni in un ciclo infinito e genera nuove goroutine per gestirle. – tux21b

7

Da Server.go, la routine di go viene generata nella funzione Serve quando viene accettata una connessione. Qui di seguito è il frammento di,: -

// Serve accepts incoming connections on the Listener l, creating a 
// new service goroutine for each. The service goroutines read requests and 
// then call srv.Handler to reply to them. 
func (srv *Server) Serve(l net.Listener) error { 
     for { 
      rw, e := l.Accept() 
       if e != nil { 
...... 
      c, err := srv.newConn(rw) 
      if err != nil { 
       continue 
      } 
      c.setState(c.rwc, StateNew) // before Serve can return 
      go c.serve() 
     } 
} 
0

Se si utilizza richiesta XHR, assicurarsi che esempio XHR è una variabile locale.

Ad esempio, xhr = new XMLHttpRequest() è una variabile globale. Quando si esegue una richiesta parallela con la stessa variabile xhr, si riceve solo un risultato. Quindi, devi dichiarare xhr localmente come questo var xhr = new XMLHttpRequest().

Problemi correlati