Implementei a limitação de taxa simples usando o HaProxy de maneira semelhante à maneira como o StackExchange o faz com o HaProxy. Estou tentando torná-lo um pouco mais avançado para que haja vários limites de limitação de taxa.
Por exemplo, limite os clientes que solicitam:
15/minuto
60/hora
360/dia
Parece que preciso de vários stick-tables para armazenar os mesmos dados com diferentes taxas de amostragem. A documentação afirma:
Existe apenas uma stick-table por proxy. No momento em que escrevo este documento, não parece útil ter várias tabelas por proxy. Se isso for necessário, simplesmente crie um back-end fictício com uma tabela de sticks e faça referência a ele.
Infelizmente, estou tendo um trabalho infernal tentando descobrir como armazenar os dados nas tabelas fictícias de back-end.
Também estou aberto a outros métodos, o HaProxy simplesmente parecia um caminho promissor e, como já o temos no ambiente, fazia sentido. Todas as sugestões são apreciadas.
Eu estava apenas tentando fazer isso sozinho, não estava tendo sorte e decidi recorrer ao meu google-fu. O melhor resultado para mim ao procurar vários níveis de limitação de taxa foi esse e fiquei muito animado. Então vi que não tinha respostas e inicialmente caí em um poço existencial de desespero. Depois de me desenterrar, continuei hackeando e, por um golpe de sorte, pareço ter descoberto como fazer isso pelo menos para o que eu precisava. Talvez funcione para você também.
Haproxy é muito, muito legal, e estou animado para começar a usá-lo no lugar de nossa solução de balanceamento de carga atual, mas stick-tables são um monstro para você entender. Nessa frente, encontrei um princípio geral que parece estar me ajudando, e é referir-se explicitamente a cadastick table pelo nome quando estiver tentando fazer uma configuração com várias tabelas stick. O comportamento padrão, onde o nome é implícito (supõe-se que seja o back-end em que você está), é ótimo... exceto quando você começa a tentar ficar chique com várias tabelas stick. É por isso que na minha configuração abaixo, algumas delas são mais detalhadas do que deveriam. Eu apenas acho mais fácil seguir a lógica dessa maneira. De qualquer forma, aqui vai (observe que esta contagem é baseada em cookies para um aplicativo Moodle, não no IP, e está usando a v1.5.11 do haproxy):
Então, o que isso está fazendo é definir um contador para registrar a taxa por 10s e outro para registrar a taxa por 60s. Observe que ainda não está usando esses contadores para fazer qualquer limitação de taxa. Mas você pode verificar via:
Que os contadores de taxa estão sendo mantidos separadamente.
Eu queria descobrir a configuração mínima necessária para que esses contadores realmente incrementassem, e é por isso que você vê "FALSO" no final da declaração "rejeição de conteúdo de solicitação tcp". Apenas definir as acls com os contadores não fará com que eles sejam incrementados. Você tem que realmente usar o acl. Colocar "FALSE" no final simplesmente permite que eu use o acl sem nunca satisfazer a condição de realmente rejeitar a solicitação. Provavelmente retirarei o "FALSO" assim que decidir sobre alguns números reais para esses ACLs.
A verdadeira chave para fazer com que várias tabelas stick funcionem é fazer as definições "stick on", "track-sc{0|1|2}" e acl usando "sc{0,1,2}_inc_gpc0" no back-end onde você está realmente lidando com a solicitação. Mover qualquer um deles para o back-end dynamic_60 fez com que a contagem parasse de funcionar. Eu acho que o raciocínio é que não faz sentido rastrear ou aplicar acls a um back-end que não está atendendo a solicitações porque na verdade não tem as solicitações passando para obter informações. Dito isso, tenho certeza de que outros terão explicações melhores. Eu sou muito novo para haproxy.
A próxima pergunta que fiz foi: estou limitado a apenas rastrear 3 coisas (já que as configurações "track-sc" vão apenas de 0-2). Eu acredito que, sim, você só pode rastrear as três coisas. Mas importante, são 3 coisas porback-end que realmente atende a uma solicitação. Assim, por exemplo, se, como eu, você deseja fazer uma limitação de taxa diferente para conteúdo estático e conteúdo dinâmico, pode decidir se deseja ir para um back-end "estático" ou "dinâmico" em seu front-end, com base em algo no solicitar. Em seguida, no back-end "estático", você define track-sc0 e track-sc1 nos back-ends "static" e "static_60" (se você estiver seguindo um esquema de nomenclatura semelhante à configuração que coloquei acima). Então você terá 4 stick tables para usar para tomar decisões de limitação de taxa. Taxas de 10 e 60 para conteúdo dinâmico e estático. Use o terceiro contador e acho que você poderia obter seus 3 níveis, mas acho que seria o limite.
Eu também mexi com esse problema por algum tempo. A solução de David Ackerman está funcionando bem, mas pode ser simplificada com o uso de um segundo General Purpose Registers (disponível desde o HAProxy 1.9+) se você precisar apenas de dois limites. Esta é a minha solução para limitar os pedidos por minuto e por dia.
Esta solução também não contabiliza pedidos bloqueados