2015-05-20 10 views
17
package main 

import (
    "io" 
    "net/http" 
) 

func hello(w http.ResponseWriter, r *http.Request) { 
    io.WriteString(w, "Hello world!\n") 
} 

func main() { 
    http.HandleFunc("/", hello) 
    http.ListenAndServe(":8000", nil) 
} 

Mam kilka niewiarygodnie podstawowych serwerów HTTP i wszystkie one wykazują ten problem.Dlaczego mój serwer Hello World go zostaje zmiażdżony przez 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 

Przy mniejszej wartości współbieżności rzeczy wciąż się przewracają. Dla mnie sprawa wydaje się, aby pokazać się wokół 5k-6k znakiem zwykle:

$ 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 

I rzeczywiście, można upuścić współbieżność całkowicie i problem nadal (czasami) dzieje:

$ 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 zastanawiam się, czy gdzieś trafiam w jakiś system operacyjny? Jak mam powiedzieć? A jak złagodzę?

+1

'ab' nie jest bardzo dobry, a serwer go http na razie go wykonuje. 'ab' działa również bardzo słabo na osx. Wykorzystujesz niektóre zasoby lokalne, takie jak dostępne gniazda. – JimB

+0

Jak uruchomić swój serwer? Nie widzę, żebyś ustawiał GOMAXPROCS w dowolnym miejscu. –

+4

Myślę, że domyślnie połączenie z serwerem Go nie jest zamknięte, więc może być ponownie użyte, ale wydaje się, że 'ab' nie używa ich ponownie ani nie zamyka wystarczająco szybko, aby osiągnąć maksymalne otwarte połączenie. Możesz spróbować ustawić 'r.Close' na' true' w twoim programie obsługi (nie przetestowałem go). – siritinga

Odpowiedz

26

Krótko mówiąc, brakuje portów.

Domyślny port efemerycznego portu na osx to 49152-65535, który ma tylko 16 383 porty. Ponieważ każde żądanie ab jest (bez zachowania ciągłości w pierwszych przykładach), każde nowe żądanie przyjmuje inny port.

Podczas korzystania z każdego portu jest on umieszczany w kolejce, w której oczekuje na TCP "Maksymalny czas życia segmentu", który jest skonfigurowany na 15 sekund na osx. Więc jeśli użyjesz więcej niż 16 383 portów w 15 sekund, będziesz skutecznie dławiony przez system operacyjny w kolejnych połączeniach. W zależności od tego, który proces zostanie wcześniej zakończony, uzyskasz połączenie z serwerem lub zawiedzie się od ab.

można złagodzić to za pomocą generatora http/1.1 zdolny obciążenia jak wrk lub używając podtrzymywanie (-k) opcję ab, tak, że połączenia są ponownie wykorzystywane na podstawie ustawień współbieżności narzędzia.

Teraz kod serwera, który testujesz, robi tak mało, że generator obciążeń jest opodatkowany tak samo, jak sam serwer, a lokalny os i stos sieciowy prawdopodobnie wnoszą duży wkład. Jeśli chcesz przetestować serwer http, lepiej wykonać jakąś sensowną pracę z wielu klientów nie działających na tym samym komputerze.

+0

W tym przypadku moim głównym celem nie jest porównywanie serwera aplikacji, naprawdę staram się odczuć obciążenie wydajności całego stosu Kubernetes względem samego serwera aplikacji, ale widziałem pewne mylące wyniki, których nie miałem. zrozumieć na drodze do tego celu. –

+0

Jak dowiem się, ile obecnie dostępnych jest portów efemerycznych? –

+0

Ponadto, z ciekawości, z maszyną wirtualną, efemeryczne porty używane w systemie-gościu wpłyną na hosta w jakikolwiek sposób? tzn. czy mogę obrócić kilka maszyn wirtualnych z 'wrk' /' ab'/'httperf', aby ominąć ograniczenie efemerycznego portu OS X? –