Różnica między globalnymi maxconn i server maxconn haproxy

91

Mam pytanie odnośnie mojej konfiguracji haproxy:

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log         127.0.0.1 syslog emerg
    maxconn     4000
    quiet
    user        haproxy
    group       haproxy
    daemon
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will 
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode        http
    log         global
    option      abortonclose
    option      dontlognull
    option      httpclose
    option      httplog
    option      forwardfor
    option      redispatch
    timeout connect 10000 # default 10 second time out if a backend is not found
    timeout client 300000 # 5 min timeout for client
    timeout server 300000 # 5 min timeout for server
    stats       enable

listen  http_proxy  localhost:81

    balance     roundrobin
    option      httpchk GET /empty.html
    server      server1 myip:80 maxconn 15 check inter 10000
    server      server2 myip:80 maxconn 15 check inter 10000

Jak widać, jest to proste, ale jestem trochę zdezorientowany, jak działają właściwości maxconn.

Na serwerze, w bloku nasłuchu, znajduje się jeden globalny i maxconn. Moje myślenie jest takie: globalne zarządza całkowitą liczbą połączeń, które haproxy jako usługa będzie kolejkować lub przetwarzać w tym samym czasie. Jeśli liczba przekroczy tę, albo zrywa połączenie, albo gromadzi się w jakimś gnieździe linuxowym? Nie mam pojęcia, co się stanie, jeśli liczba przekroczy 4000.

Następnie masz właściwość maxconn serwera ustawioną na 15. Po pierwsze, ustawiłem to na 15, ponieważ mój php-fpm, to jest przekazywanie na oddzielny serwer, ma tylko tyle procesów potomnych, których może użyć, więc upewniam się, że jestem gromadzenie żądań tutaj, zamiast w php-fpm. Co myślę, że jest szybsze.

Ale wracając do tematu, moja teoria dotycząca tej liczby jest taka, że ​​każdy serwer w tym bloku będzie miał tylko 15 połączeń naraz. Następnie połączenia będą czekać na otwarty serwer. Gdybym miał włączone pliki cookie, połączenia czekałyby na PRAWIDŁOWY otwarty serwer. Ale ja nie.

Oto pytania:

  1. Co się stanie, jeśli liczba połączeń globalnych przekroczy 4000? Czy umierają? Lub w jakiś sposób bilard w Linuksie?
  2. Czy połączenie globalne jest powiązane z połączeniami z serwerem, poza faktem, że całkowita liczba połączeń z serwerem nie może być większa niż globalna?
  3. Czy przy obliczaniu połączeń globalnych nie powinna to być liczba połączeń zsumowanych w sekcji serwera plus pewien procent dla puli? I oczywiście masz inne ograniczenia na połączeniach, ale tak naprawdę to ile chcesz wysłać do serwerów proxy?

Z góry dziękuję.

chantheman
źródło

Odpowiedzi:

167

Willy dostał odpowiedź e-mailem. Pomyślałem, że się tym podzielę. Jego odpowiedzi są pogrubione.

Mam pytanie odnośnie mojej konfiguracji haproxy:

   #---------------------------------------------------------------------
   # Global settings
   #---------------------------------------------------------------------
   global
       log         127.0.0.1 syslog emerg
       maxconn     4000
       quiet
       user        haproxy
       group       haproxy
       daemon
   #---------------------------------------------------------------------
   # common defaults that all the 'listen' and 'backend' sections will 
   # use if not designated in their block
   #---------------------------------------------------------------------
   defaults
       mode        http
       log         global
       option      abortonclose
       option      dontlognull
       option      httpclose
       option      httplog
       option      forwardfor
       option      redispatch
       timeout connect 10000 # default 10 second time out if a backend is not found
       timeout client 300000 # 5 min timeout for client
       timeout server 300000 # 5 min timeout for server
       stats       enable

   listen  http_proxy  localhost:81

       balance     roundrobin
       option      httpchk GET /empty.html
       server      server1 myip:80 maxconn 15 check inter 10000
       server      server2 myip:80 maxconn 15 check inter 10000

Jak widać, jest to proste, ale jestem trochę zdezorientowany, jak działają właściwości maxconn.

Na serwerze, w bloku nasłuchu, znajduje się jeden globalny i maxconn.

Jest też inny w bloku nasłuchiwania, który domyślnie wynosi około 2000.

Moje myślenie jest takie: połączenie globalne zarządza całkowitą liczbą połączeń, które haproxy, jako usługa, będzie kolejkować lub przetwarzać jednocześnie.

Poprawny. Jest to maksymalna liczba równoczesnych połączeń na proces.

Jeśli liczba przekroczy tę, albo zrywa połączenie, albo gromadzi się w jakimś gnieździe linuxowym?

Później po prostu przestaje akceptować nowe połączenia i pozostają one w kolejce gniazd w jądrze. Liczba gniazd w kolejce jest określana przez wartość min z (net.core.somaxconn, net.ipv4.tcp_max_syn_backlog i maxconn bloku nasłuchiwania).

Nie mam pojęcia, co się stanie, jeśli liczba przekroczy 4000.

Nadmiarowe połączenia czekają na zakończenie kolejnego, zanim zostaną zaakceptowane. Jednak dopóki kolejka jądra nie jest zapełniona, klient nawet tego nie zauważa, ponieważ połączenie jest akceptowane na poziomie TCP, ale nie jest przetwarzane. Tak więc klient zauważa tylko pewne opóźnienie w przetworzeniu żądania. Ale w praktyce maxconn bloku nasłuchiwania jest znacznie ważniejszy, ponieważ domyślnie jest mniejszy niż globalny. Maksymalne połączenie nasłuchiwania ogranicza liczbę połączeń na odbiorcę. Ogólnie rzecz biorąc, rozsądnie jest skonfigurować go dla liczby połączeń, które chcesz dla usługi, i skonfigurować globalne maxconn do maksymalnej liczby połączeń, które pozwolisz obsłużyć procesowi haproxy. Jeśli masz tylko jedną usługę, obie mogą mieć tę samą wartość. Ale jeśli masz wiele usług,

Następnie masz właściwość maxconn serwera ustawioną na 15. Po pierwsze, ustawiłem to na 15, ponieważ mój php-fpm, to jest przekazywanie na oddzielny serwer, ma tylko tyle procesów potomnych, których może użyć, więc upewniam się, że jestem gromadzenie żądań tutaj, zamiast w php-fpm. Co myślę, że jest szybsze.

Tak, nie tylko powinno być szybsze, ale także pozwala haproxy znaleźć inny dostępny serwer, kiedy tylko jest to możliwe, a także pozwala na zabicie żądania w kolejce, jeśli klient osiągnie „stop”, zanim połączenie zostanie przekazane do serwera.

Ale wracając do tematu, moja teoria dotycząca tej liczby jest taka, że ​​każdy serwer w tym bloku będzie miał tylko 15 połączeń naraz. Następnie połączenia będą czekać na otwarty serwer. Gdybym miał włączone pliki cookie, połączenia czekałyby na PRAWIDŁOWY otwarty serwer. Ale ja nie.

To jest dokładnie zasada. Istnieje kolejka na serwer proxy i kolejka na serwer. Połączenia z trwałym plikiem cookie przechodzą do kolejki serwera, a inne połączenia do kolejki proxy. Ponieważ jednak w Twoim przypadku nie jest skonfigurowany żaden plik cookie, wszystkie połączenia trafiają do kolejki proxy. Możesz spojrzeć na diagram doc / queuing.fig w źródłach haproxy, jeśli chcesz, wyjaśnia on, jak / gdzie są podejmowane decyzje.

Oto pytania:

  1. Co się stanie, jeśli liczba połączeń globalnych przekroczy 4000? Czy umierają? Lub w jakiś sposób bilard w Linuksie?

    Są w kolejce w Linuksie. Gdy przytłoczysz kolejkę jądra, zostaną one upuszczone do jądra.

  2. Czy połączenie globalne jest powiązane z połączeniami z serwerem, poza faktem, że całkowita liczba połączeń z serwerem nie może być większa niż globalna?

    Nie, ustawienia globalne i ustawienia połączenia z serwerem są niezależne.

  3. Czy przy obliczaniu połączeń globalnych nie powinna to być liczba połączeń zsumowanych w sekcji serwera plus pewien procent dla puli? I oczywiście masz inne ograniczenia na połączeniach, ale tak naprawdę to ile chcesz wysłać do serwerów proxy?

    Masz rację. Jeśli czas odpowiedzi serwera jest krótki, nie ma nic złego w ustawianiu tysięcy połączeń w kolejce, aby obsłużyć tylko kilka naraz, ponieważ znacznie skraca to czas przetwarzania żądań. Praktycznie, ustanowienie połączenia zajmuje obecnie około 5 mikrosekund w gigabitowej sieci LAN. Dlatego warto pozwolić haproxy na jak najszybszą dystrybucję połączeń ze swojej kolejki do serwera z bardzo małym maxconn. Pamiętam, że jedna witryna z grami kolejkuje ponad 30000 jednoczesnych połączeń i działa z kolejką 30 na serwer! Był to serwer Apache, a Apache jest znacznie szybszy przy małej liczbie połączeń niż przy dużych liczbach. Ale do tego naprawdę potrzebujesz szybkiego serwera, ponieważ nie Chcę, aby wszyscy klienci byli w kolejce, czekając na miejsce połączenia, ponieważ serwer czeka na przykład na bazę danych. Coś, co działa bardzo dobrze, to dedykowanie serwerów. Jeśli Twoja witryna ma wiele statystyk, możesz skierować żądania statyczne do puli serwerów (lub pamięci podręcznych), aby nie kolejkować na nich żądań statycznych i aby żądania statyczne nie zjadały drogich gniazd połączeń. Mam nadzieję, że to pomoże, Willy

chantheman
źródło
10
Dzięki za opublikowanie tego.
Tarantula
9
Mam jedną haproxy, która pośredniczy w około 200 innych backendach. Gdy backend został poddany DDOS-owi z około 300 000 konneitonów / sekundę, wszystkie inne backend umierają. Z wartością maxconn 2048 na serwerze zaplecza (pod ddos), nasz haproxy działa dobrze. Dziękuję bardzo, uratowałeś mi jedną noc :)
Hungnv