HAProxy alto uso da CPU - problema de configuração?

3

Recentemente, tivemos um aumento no tráfego, que, embora de tamanho moderado, fez com que o haproxy maximizasse um dos núcleos da CPU (e o servidor não respondia). Eu estou supondo que estou fazendo algo de forma ineficiente na configuração, e por isso gostaria de perguntar a todos os especialistas da haproxy se eles seriam tão bons a ponto de criticar meu arquivo de configuração abaixo (principalmente de uma perspectiva de performance).

A configuração destina-se a distribuir entre um grupo de servidores de aplicativos http, um grupo de servidores que manipula conexões de websockets (com vários processos separados em portas diferentes) e um servidor de arquivos estáticos. Está funcionando bem desde o problema de desempenho. (Alguns detalhes foram redigidos.)

Qualquer orientação que você possa oferecer seria muito apreciada!

HAProxy v1.4.8

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
        global
                daemon
                maxconn         100000
                log             127.0.0.1 local0 notice
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
        defaults
                log                     global
                mode                    http
                option                  httplog
                option                  httpclose               #http://serverfault.com/a/104782/52811
                timeout connect         5000ms
                timeout client          50000ms
                timeout server          5h                      #long timeouts to stop WS drops - when v1.5 is stable, use 'timeout tunnel';
#---------------------------------------------------------------------
# FRONTEND
#---------------------------------------------------------------------
        frontend public
                bind *:80
                maxconn         100000
                reqidel ^X-Forwarded-For:.*                     #Remove any x-forwarded-for headers
                option forwardfor                               #Set the forwarded for header (needs option httpclose)

                default_backend app
                redirect prefix http://xxxxxxxxxxxxxxxxx code 301 if { hdr(host) -i www.xxxxxxxxxxxxxxxxxxx }
                timeout client  5h                              #long timeouts to stop WS drops - when v1.5 is stable, use 'timeout tunnel';

        # ACLs
        ##########
        acl static_request hdr_beg(host) -i i.
        acl static_request hdr_beg(host) -i static.
        acl static_request path_beg /favicon.ico /robots.txt
        acl test_request hdr_beg(host) -i test.
        acl ws_request hdr_beg(host) -i ws
        # ws11
        acl ws11x1_request hdr_beg(host) -i ws11x1
        acl ws11x2_request hdr_beg(host) -i ws11x2
        acl ws11x3_request hdr_beg(host) -i ws11x3
        acl ws11x4_request hdr_beg(host) -i ws11x4
        acl ws11x5_request hdr_beg(host) -i ws11x5
        acl ws11x6_request hdr_beg(host) -i ws11x6
        # ws12
        acl ws12x1_request hdr_beg(host) -i ws12x1
        acl ws12x2_request hdr_beg(host) -i ws12x2
        acl ws12x3_request hdr_beg(host) -i ws12x3
        acl ws12x4_request hdr_beg(host) -i ws12x4
        acl ws12x5_request hdr_beg(host) -i ws12x5
        acl ws12x6_request hdr_beg(host) -i ws12x6

        # Which backend....
        ###################
        use_backend static   if static_request
        #ws11
        use_backend ws11x1 if ws11x1_request
        use_backend ws11x2 if ws11x2_request
        use_backend ws11x3 if ws11x3_request
        use_backend ws11x4 if ws11x4_request
        use_backend ws11x5 if ws11x5_request
        use_backend ws11x6 if ws11x6_request
        #ws12
        use_backend ws12x1 if ws12x1_request
        use_backend ws12x2 if ws12x2_request
        use_backend ws12x3 if ws12x3_request
        use_backend ws12x4 if ws12x4_request
        use_backend ws12x5 if ws12x5_request
        use_backend ws12x6 if ws12x6_request
#---------------------------------------------------------------------
# BACKEND - APP
#---------------------------------------------------------------------
        backend app
                timeout server          50000ms #To counter the WS default
                mode http
                balance roundrobin
                option httpchk HEAD /upchk.txt
                server app1 app1:8000             maxconn 100000 check
                server app2 app2:8000             maxconn 100000 check
                server app3 app3:8000             maxconn 100000 check
                server app4 app4:8000             maxconn 100000 check
#---------------------------------------------------------------------
# BACKENDs - WS
#---------------------------------------------------------------------
#Server ws11
        backend ws11x1
                server ws11 ws11:8001 maxconn 100000
        backend ws11x2
                server ws11 ws11:8002 maxconn 100000
        backend ws11x3
                server ws11 ws11:8003 maxconn 100000
        backend ws11x4
                server ws11 ws11:8004 maxconn 100000
        backend ws11x5
                server ws11 ws11:8005 maxconn 100000
        backend ws11x6
                server ws11 ws11:8006 maxconn 100000
#Server ws12
        backend ws12x1
                server ws12 ws12:8001 maxconn 100000
        backend ws12x2
                server ws12 ws12:8002 maxconn 100000
        backend ws12x3
                server ws12 ws12:8003 maxconn 100000
        backend ws12x4
                server ws12 ws12:8004 maxconn 100000
        backend ws12x5
                server ws12 ws12:8005 maxconn 100000
        backend ws12x6
                server ws12 ws12:8006 maxconn 100000
#---------------------------------------------------------------------
# BACKEND - STATIC
#---------------------------------------------------------------------
        backend static
                server static1 static1:80   maxconn 40000
    
por UpTheCreek 26.09.2014 / 10:25

3 respostas

5

100.000 conexões são muito ... Você está pressionando tanto? Se assim for ... talvez dividindo o frontend de forma que ele se ligue em um ip para conteúdo estático e um ip para o conteúdo do app e então execute as variantes static e app como processos haproxy separados (supondo que você tenha um segundo core / cpu no servidor) ...

Se nada mais, reduzirá o uso ao aplicativo ou aos fluxos estáticos ...

Se eu estou lembrando minha classe de rede 101 corretamente ... HaProxy não deve ser capaz de acessar 100,000 conexões para ws12:8001 ou qualquer outro host backend: port por causa do limite de porta ~ 65536 que está mais próximo 28232 na maioria dos sistemas ( cat /proc/sys/net/ipv4/ip_local_port_range ). Você pode estar exaurindo as portas locais, o que poderia, por sua vez, fazer com que a CPU parasse enquanto aguardava a liberação das portas.

Talvez a redução das conexões máximas para cada back-end para mais perto de 28000 aliviasse o problema? Ou alterar o intervalo de portas locais para ser mais inclusivo?

    
por 29.09.2014 / 16:51
3

Dê uma olhada na configuração nbproc e veja se isso ajuda utilizando mais de um núcleo. Para a maioria dos balanceadores de carga de hardware, a quantidade de tráfego que você pode manipular é limitada pela sua cpu / memória do balanceador de carga.

1.5) Increasing the overall processing power
--------------------------------------------
On multi-processor systems, it may seem to be a shame to use only one processor,
eventhough the load needed to saturate a recent processor is far above common
usage. Anyway, for very specific needs, the proxy can start several processes
between which the operating system will spread the incoming connections. The
number of processes is controlled by the 'nbproc' parameter in the 'global'
section. It defaults to 1, and obviously works only in 'daemon' mode. One
typical usage of this parameter has been to workaround the default per-process
file-descriptor limit that Solaris imposes to user processes.

Example :
---------

    global
        daemon
        quiet
        nbproc  2
    
por 30.09.2014 / 06:38
2

Fora da configuração do haproxy, isso ajudaria a fazer alguns ajustes de rede.

Uma coisa específica que pode ajudar é garantir que suas interfaces de rede não sejam fixadas em uma única CPU (supondo que você esteja usando várias interfaces). Se você estiver executando o haproxy no Linux, você pode verificar o saldo da seguinte forma:

egrep CPU\|eth /proc/interrupts

Por exemplo, isso mostra que as interrupções para eth0 e eth1 estão sendo manipuladas por CPUs diferentes:

$ egrep CPU\|eth /proc/interrupts
      CPU0        CPU1        CPU2    CPU3
103:  3515635238  0           0       0          IR-PCI-MSI-edge  eth0
104:  0           1976927064  0       0          IR-PCI-MSI-edge  eth1

Considerando que isso os mostra sendo manipulados pela mesma CPU:

$ egrep CPU\|eth /proc/interrupts
      CPU0        CPU1  CPU2  CPU3
272:  1526254507  0     0     0     Dynamic-irq  eth0
273:  4877925     0     0     0     Dynamic-irq  eth1

Você desejará ativar a afinidade de smp para essas interfaces. Para o exemplo acima, você pode fazer o seguinte:

echo 010 > /proc/irq/272/smp_affinity
echo 010 > /proc/irq/273/smp_affinity
    
por 30.09.2014 / 06:31

Tags