Usando o HAProxy para equilibrar solicitações lentas e rápidas em vários back-ends

2

Eu sou novo em usar o HAProxy para balancear a carga do meu aplicativo, que atualmente executa cinco instâncias de aplicativos de back-end. Minha configuração é relativamente simples. Eu tenho um aplicativo Ruby que usa fibras, EventMachine e thin para tentar mantê-lo como não bloqueante quanto possível. Assim, a maioria das solicitações retornará rapidamente ou, no mínimo, não bloquearão o servidor de aplicativos, para que possa atender a várias solicitações de uma só vez.

No entanto, existem algumas solicitações (como uploads de imagens que precisam acessar os comandos do shell), que podem ser lentas e bloquear o servidor de aplicativos.

O que eu estou achando é que um estilo round-robin de balanceamento não faz sentido aqui, já que as requisições que poderiam ser manipuladas simultaneamente e retornadas rapidamente são atrasadas por trás das solicitações lentas. Qual é a melhor maneira de lidar com isso?

Eu considerei:

  • Ter uma verificação de integridade que é executada com freqüência (digamos, a cada 250ms) para verificar se o servidor está respondendo. Se não for, suponha que ele esteja "inativo" (provavelmente bloqueando uma solicitação longa), o que fará com que o HAProxy roteie solicitações em torno dele. No entanto, neste cenário, existe a possibilidade de todas as 5 instâncias ficarem bloqueadas.

  • Tenha uma lista pré-definida de URLs de solicitações lentas, designe 2 ou 3 dos back-ends do aplicativo para lidar apenas com solicitações lentas e direcione todos os outros para os back-ends "rápidos". Em teoria, as solicitações rápidas nunca serão bloqueadas, mas essa abordagem parece um pouco mais delicada, já que precisarei me certificar de que, se a URL já tiver mudado, lembro de atualizar minha configuração do HAProxy.

Eu acho que a última abordagem é provavelmente a melhor, mas como o Devops não é o meu ponto strong, eu pensei em checar e ver qual é a melhor prática neste cenário.

Claro, "melhor prática" é provavelmente ter todas as solicitações de longa execução movidas para tarefas em segundo plano, mas, neste caso, vamos supor que não tenho tempo para isso agora se for evitável: -)

    
por Riley Dutton 14.03.2013 / 17:48

1 resposta

3

Um pouco da coluna A, um pouco da coluna B:)

Por causa do tempo de atividade, você definitivamente deveria estar usando verificações de saúde em HAProxy, independentemente de qualquer outra coisa. Se um de seus nós de back-end ficar inativo, você deseja que o HAProxy pare de enviar solicitações para ele. A falha não precisa estar em sua aplicação, pode ser hardware, rede, qualquer coisa. Isso é bem simples de configurar:

option httpchk GET /test HTTP/1.0\r\n

250 ms soa como um cheque muito frequente. Nesse ritmo, seus servidores de back-end podem gastar muito tempo apenas processando verificações de integridade. Você precisa compensar o custo das verificações de integridade em termos de sobrecarga do aplicativo versus a rapidez com que você deseja que os nós mortos sejam colocados offline.

A segunda estratégia é uma que eu usei antes. Descubra o número total de conexões simultâneas que seu aplicativo pode manipular. Em seguida, no HAProxy, divida as solicitações em velocidade lenta e rápida e aloque uma proporção do total de conexões para cada uma. Por exemplo,

frontend myfrontend
    bind *:80
    acl url-slow path /some-long-running-request
    use_backend slow-backend if url-slow
    default_backend regular-backend

backend slow-backend
    ...
    server backend1 1.2.3.4:80 maxconn 10

backend regular-backend
    ...
    server backend1 1.2.3.4.:80 maxconn 90

Portanto, o backend1 pode manipular 100 conexões simultâneas. Acima, alocamos 90 conexões a solicitações "regulares" e 10 conexões a solicitações lentas. Mesmo se você usar todas as suas conexões lentas, as solicitações "regulares" ainda serão processadas.

Boa sorte!

    
por 18.03.2013 / 00:56

Tags