2015-05-20 2 views
17

Ho un paio di server HTTP incredibilmente di base e tutti presentano questo problemaPerché il mio server Hello World go viene schiacciato da ApacheBench?

$ ab -c 1000 -n 10000 http://127.0.0.1:8000/ 
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
Licensed to The Apache Software Foundation, http://www.apache.org/ 

Benchmarking 127.0.0.1 (be patient) 
Completed 1000 requests 
Completed 2000 requests 
Completed 3000 requests 
Completed 4000 requests 
Completed 5000 requests 
apr_socket_recv: Connection refused (61) 
Total of 5112 requests completed 

Con un valore di concorrenza minore, le cose continuano a cadere. Per me, il problema sembra presentarsi intorno al marchio 5k-6K solito:

$ ab -c 10 -n 10000 http://127.0.0.1:8000/ 
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
Licensed to The Apache Software Foundation, http://www.apache.org/ 

Benchmarking 127.0.0.1 (be patient) 
Completed 1000 requests 
Completed 2000 requests 
Completed 3000 requests 
Completed 4000 requests 
Completed 5000 requests 
Completed 6000 requests 
apr_socket_recv: Operation timed out (60) 
Total of 6277 requests completed 

E infatti, è possibile eliminare la concorrenza del tutto e il problema ancora (a volte) accade:

$ ab -c 1 -n 10000 http://127.0.0.1:8000/ 
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
Licensed to The Apache Software Foundation, http://www.apache.org/ 

Benchmarking 127.0.0.1 (be patient) 
Completed 1000 requests 
Completed 2000 requests 
Completed 3000 requests 
Completed 4000 requests 
Completed 5000 requests 
Completed 6000 requests 
apr_socket_recv: Operation timed out (60) 
Total of 6278 requests completed 

I non posso fare a meno di chiedermi se sto colpendo qualche tipo di limite del sistema operativo da qualche parte? Come lo direi? E come potrei mitigare?

+1

'ab' non è molto buono, e il server Go http lo esegue molto lontano. 'ab' funziona molto male su osx. Stai esaurendo alcune risorse locali, come le prese disponibili. – JimB

+0

Come si avvia il server? Non vedo che tu abbia impostato GOMAXPROCS ovunque. –

+4

Penso che per impostazione predefinita, la connessione del server Go non sia chiusa, quindi può essere riutilizzata, ma sembra che 'ab' non sta riutilizzando né chiudendo abbastanza velocemente in modo che venga raggiunta la connessione massima aperta. Puoi provare a impostare 'r.Close' su' true' nel tuo gestore (non l'ho ancora testato). – siritinga

risposta

26

In breve, si sta esaurendo le porte.

L'intervallo di porte temporanee predefinito su osx è 49152-65535, che è solo 16.383 porte. Poiché ogni richiesta ab è (senza keepalive nei primi esempi), ogni nuova richiesta richiede un'altra porta.

Come ogni porta viene utilizzata, viene messa in coda dove attende il tcp "Maximum Segment Lifetime", che è configurato per essere di 15 secondi su osx. Quindi se usi più di 16.383 porte in 15 secondi, il sistema operativo ti farà rallentare ulteriormente su ulteriori connessioni. A seconda di quale processo esaurisce prima le porte, si ottengono errori di connessione dal server o si blocca da ab.

è possibile attenuare questo utilizzando un generatore di http/1.1 carico capace come wrk, o utilizzando il keepalive (-k) opzione per la ab, in modo che le connessioni sono riutilizzati in base alle impostazioni concorrenza dello strumento.

Ora, il codice server utilizzato per il benchmarking fa così poco, che il generatore di carico viene tassato tanto quanto il sever stesso, con il sistema operativo locale e lo stack di rete che probabilmente forniscono un buon contributo. Se si desidera eseguire il benchmark di un server http, è preferibile eseguire un lavoro significativo da più client non in esecuzione sulla stessa macchina.

+0

In questo caso, il mio obiettivo principale non è quello di confrontare il server delle app, sto davvero cercando di capire l'overhead delle prestazioni di un intero stack di Kubernetes rispetto al server delle app stesso, ma ho visto alcuni risultati confusi che non ho capire sulla strada per questo obiettivo. –

+0

Come faccio a sapere quante porte effimere sono attualmente disponibili? –

+0

Inoltre, per curiosità, con una macchina virtuale, le porte effimere utilizzate all'interno di un SO guest influiscono in qualche modo sull'host? Ad esempio, potrei creare un gruppo di VM che eseguono 'wrk' /' ab'/'httperf' per aggirare la limitazione della porta effimera di OS X? –