Diferença entre maxconn global e haproxy maxconn do servidor

91

Tenho uma pergunta sobre minha configuração 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

Como você pode ver, é simples, mas estou um pouco confuso sobre como funcionam as propriedades maxconn.

Existe o global e o maxconn no servidor, no bloco de escuta. Meu pensamento é o seguinte: o global gerencia o número total de conexões que o haproxy, como um serviço, irá enfileirar ou processar ao mesmo tempo. Se o número ficar acima disso, ele interrompe a conexão ou se agrupa em algum soquete Linux? Não tenho ideia do que acontece se o número ficar maior que 4000.

Então você tem a propriedade maxconn do servidor definida como 15. Primeiro, eu defini isso como 15 porque meu php-fpm, está encaminhando para um servidor separado, tem apenas tantos processos filhos que pode usar, então tenho certeza que estou agrupando as solicitações aqui, em vez de no php-fpm. O que eu acho mais rápido.

Mas voltando ao assunto, minha teoria sobre esse número é que cada servidor desse bloco receberá apenas 15 conexões por vez. E então as conexões esperarão por um servidor aberto. Se eu tivesse os cookies ativados, as conexões esperariam pelo servidor CORRETO aberto. Mas eu não quero.

Então, as perguntas são:

  1. O que acontece se as conexões globais ficarem acima de 4000? Eles morrem? Ou pool no Linux de alguma forma?
  2. A conexão global está relacionada às conexões do servidor, a não ser pelo fato de você não poder ter um número total de conexões do servidor maior do que global?
  3. Ao descobrir as conexões globais, não deveria ser a quantidade de conexões adicionadas na seção do servidor, mais uma certa porcentagem para pool? E obviamente você tem outras restrições nas conexões, mas realmente é quantas você deseja enviar para os proxies?

Agradeço antecipadamente.

chantheman
fonte

Respostas:

166

Willy me respondeu por e-mail. Eu pensei em compartilhar isso. Suas respostas estão em negrito.

Tenho uma pergunta sobre minha configuração 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

Como você pode ver, é simples, mas estou um pouco confuso sobre como funcionam as propriedades maxconn.

Existe o global e o maxconn no servidor, no bloco de escuta.

E também há outro no bloco de escuta que tem como padrão algo como 2000.

Meu pensamento é o seguinte: o global gerencia o número total de conexões que o haproxy, como serviço, irá que ou processará de uma só vez.

Corrigir. É o número máximo por processo de conexões simultâneas.

Se o número ficar acima disso, ele interrompe a conexão ou se agrupa em algum soquete Linux?

Mais tarde, ele simplesmente para de aceitar novas conexões e elas permanecem na fila de soquetes no kernel. O número de sockets que podem ser enfileirados é determinado pelo mínimo de (net.core.somaxconn, net.ipv4.tcp_max_syn_backlog e maxconn do bloco de escuta).

Não tenho ideia do que acontece se o número ficar maior que 4000.

As conexões excedentes aguardam a conclusão de outra antes de serem aceitas. Porém, enquanto a fila do kernel não estiver saturada, o cliente nem percebe, pois a conexão é aceita no nível TCP, mas não é processada. Assim, o cliente apenas nota algum atraso no processamento do pedido. Mas, na prática, o maxconn do bloco de escuta é muito mais importante, já que por padrão é menor do que o global. O maxconn do ouvinte limita o número de conexões por ouvinte. Em geral, é aconselhável configurá-lo para o número de conexões que você deseja para o serviço e configurar o maxconn global para o número máximo de conexões que você permite que o processo haproxy manipule. Quando você tem apenas um serviço, ambos podem ser definidos com o mesmo valor. Mas quando você tem muitos serviços,

Então você tem a propriedade maxconn do servidor definida como 15. Primeiro, eu defini isso como 15 porque meu php-fpm, está encaminhando para um servidor separado, tem apenas tantos processos filhos que pode usar, então tenho certeza que estou agrupando as solicitações aqui, em vez de no php-fpm. O que eu acho mais rápido.

Sim, não só deve ser mais rápido, mas permite ao haproxy encontrar outro servidor disponível sempre que possível, e também permite matar a solicitação na fila se o cliente clicar em "parar" antes que a conexão seja encaminhada para o servidor.

Mas voltando ao assunto, minha teoria sobre esse número é que cada servidor neste bloco receberá apenas 15 conexões por vez. E então as conexões esperarão por um servidor aberto. Se eu tivesse os cookies ativados, as conexões esperariam pelo servidor CORRETO aberto. Mas eu não quero.

Esse é exatamente o princípio. Existe uma fila por proxy e uma fila por servidor. As conexões com um cookie de persistência vão para a fila do servidor e outras conexões vão para a fila do proxy. No entanto, como no seu caso nenhum cookie está configurado, todas as conexões vão para a fila de proxy. Você pode olhar o diagrama doc / queuing.fig nas fontes haproxy se desejar, ele explica como / onde as decisões são tomadas.

Então, as perguntas são:

  1. O que acontece se as conexões globais ficarem acima de 4000? Eles morrem? Ou pool no Linux de alguma forma?

    Eles estão na fila no Linux. Depois de sobrecarregar a fila do kernel, eles são descartados no kernel.

  2. A conexão global está relacionada às conexões do servidor, a não ser pelo fato de você não poder ter um número total de conexões do servidor maior do que global?

    Não, as configurações globais e de conexão do servidor são independentes.

  3. Ao descobrir as conexões globais, não deveria ser a quantidade de conexões adicionadas na seção do servidor, mais uma certa porcentagem para o pool? E obviamente você tem outras restrições nas conexões, mas realmente é quantas você deseja enviar para os proxies?

    Você acertou. Se o tempo de resposta do seu servidor for curto, não há nada de errado em enfileirar milhares de conexões para atender apenas algumas de cada vez, porque isso reduz substancialmente o tempo de processamento da solicitação. Praticamente, estabelecer uma conexão hoje em dia leva cerca de 5 microssegundos em uma LAN gigabit. Portanto, faz muito sentido deixar o haproxy distribuir as conexões o mais rápido possível de sua fila para um servidor com um maxconn muito pequeno. Lembro-me de um site de jogos enfileirando mais de 30000 conexões simultâneas e funcionando com uma fila de 30 por servidor! Era um servidor apache, e o apache é muito mais rápido com um pequeno número de conexões do que com um grande número. Mas para isso você realmente precisa de um servidor rápido, porque você não Não quero ter todos os seus clientes enfileirados esperando por um slot de conexão porque o servidor está esperando por um banco de dados, por exemplo. Também algo que funciona muito bem é dedicar servidores. Se o seu site tiver muitos estáticos, você pode direcionar os pedidos estáticos para um pool de servidores (ou caches) para que você não enfileire os pedidos estáticos neles e que os pedidos estáticos não comam slots de conexão caros. Espero que isso ajude, Willy

chantheman
fonte
10
Obrigado por postar isso.
Tarantula
9
Eu tenho um haproxy que atua como proxy para cerca de 200 outros back-end. Uma vez que um back-end foi editado por DDOS com cerca de ~ 300k conneitons / segundo, todos os outros back-end morrem. Com o valor maxconn 2048 no servidor backend (sob ddos), nosso haproxy funciona bem. Muito obrigado, você me salvou uma noite :)
hungnv