Nginx - O que a opção nodelay faz ao limitar solicitações?

11

Com o módulo nginx HttpLimitReq , as solicitações podem ser limitadas por IP. No entanto, não estou entendendo o que a opção "nodelay" faz.

Se as solicitações excedentes dentro do atraso de burst limite não forem necessárias, você deve usar o nodelay

limit_req   zone=one  burst=5  nodelay;
Xeoncross
fonte

Respostas:

11

A documentação aqui tem uma explicação que soa como o que você deseja saber:

A diretiva especifica a zona (zona) e as explosões máximas possíveis de solicitações (burst). Se a taxa exceder as demandas descritas na zona, a solicitação será atrasada, para que as consultas sejam processadas em uma determinada velocidade

Pelo que entendi, as solicitações excedentes serão adiadas (demorem mais tempo e esperem até que possam ser atendidas), com as nodelayopções em que o atraso não é usado e as solicitações em excesso são negadas com um erro 503.

Esta postagem no blog ( archive.org ) fornece uma boa explicação de como o limite de taxa funciona no nginx:

Se você é como eu, provavelmente está se perguntando o que realmente significa. Aqui está o truque: substitua a palavra 'burst' por 'bucket' e assuma que cada usuário recebe um bucket com 5 tokens. Sempre que excederem a taxa de 1 solicitação por segundo, eles deverão pagar um token. Depois que eles gastam todos os seus tokens, eles recebem uma mensagem de erro HTTP 503, que basicamente se tornou o padrão para 'recuar, cara!'.

coredump
fonte
4
Eu acho que você está incorreto, o manual do nginx declara: "Solicitações excessivas são adiadas até que seu número exceda o tamanho máximo de intermitência". Observe que, até exceder o número máximo de burst, significa um significado totalmente diferente do que o burst que você disse. Você também confundiu a sincronização com solicitações em excesso , acredito que solicitações em excesso significa que ela está acima da zona, enquanto ainda pode estar abaixo da explosão máxima .
Hendy Irawan
10

TL; DR: a opção nodelay é útil se você deseja impor um limite de taxa sem restringir o espaçamento permitido entre solicitações.

Foi difícil digerir as outras respostas e descobri nova documentação do Nginx com exemplos que respondem a isso: https://www.nginx.com/blog/rate-limiting-nginx/

Aqui está a parte pertinente. Dado:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

location /login/ {
  limit_req zone=mylimit burst=20;
  ...
}

O parâmetro burst define quantas solicitações um cliente pode fazer além da taxa especificada pela zona (com nossa zona de limite ilimitado de amostra, o limite da taxa é de 10 solicitações por segundo ou 1 a cada 100 milissegundos). Uma solicitação que chega antes de 100 milissegundos após a anterior ser colocada em uma fila e aqui estamos configurando o tamanho da fila para 20.

Isso significa que, se 21 solicitações chegarem de um determinado endereço IP simultaneamente, o NGINX encaminhará a primeira para o grupo de servidores upstream imediatamente e colocará as 20 restantes na fila. Em seguida, encaminha uma solicitação na fila a cada 100 milissegundos e retorna 503 ao cliente apenas se uma solicitação de entrada fizer com que o número de solicitações na fila ultrapasse 20.

Se você adicionar nodelay:

location /login/ {
  limit_req zone=mylimit burst=20 nodelay;
  ...
}

Com o parâmetro nodelay, o NGINX ainda aloca slots na fila de acordo com o parâmetro burst e impõe o limite de taxa configurado, mas não espaçando o encaminhamento de solicitações na fila. Em vez disso, quando uma solicitação chega "muito cedo", o NGINX a encaminha imediatamente, desde que haja um slot disponível na fila. Ele marca esse slot como "ocupado" e não o libera para uso por outra solicitação até que o tempo apropriado tenha passado (no nosso exemplo, após 100 milissegundos).

Mark Woon
fonte
6

A maneira como eu vejo é a seguinte:

  1. As solicitações serão atendidas o mais rápido possível até que a taxa da zona seja excedida. A taxa de zona é "em média", por isso, se a sua taxa é 1r/se explodiu 10você pode ter 10 pedidos em 10 segunda janela.

  2. Após a taxa da zona ser excedida:

    uma. Sem nodelay, mais solicitações burstserão atrasadas.

    b. Com nodelay, mais solicitações burstserão atendidas o mais rápido possível.

  3. Depois de burstexcedido, o servidor retornará uma resposta de erro até que a janela de intermitência expire. por exemplo, para taxa 1r/se burst 10, o cliente precisará esperar até 10 segundos para a próxima solicitação aceita.

Hendy Irawan
fonte
3

A configuração define se as solicitações serão atrasadas para que estejam em conformidade com a taxa desejada ou se serão simplesmente rejeitadas ... um pouco, se a limitação da taxa for gerenciada pelo servidor ou se a responsabilidade for passada ao cliente.

nodelay presente

Os pedidos serão tratados o mais rápido possível; quaisquer pedidos enviados acima do limite especificado serão rejeitados com o código definido comolimit_req_status

nodelay ausente (aka atrasado)

As solicitações serão tratadas a uma taxa que esteja em conformidade com o limite especificado. Assim, por exemplo, se uma taxa é definida como 10 req / s, cada solicitação será tratada em> = 0,1 (1 / taxa) segundos, não permitindo que a taxa seja excedida, mas permitindo que as solicitações sejam copiadas. Se houver solicitações de backup suficientes para estourar o bucket (o que também seria impedido por um limite de conexão simultâneo), elas serão rejeitadas com o código definido como limit_req_status.

Os detalhes sangrentos estão aqui: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 em que essa lógica entra em ação quando o limite ainda não foi ultrapassado e agora o atraso opcionalmente será aplicado à solicitação. A aplicação nodelayespecífica da diretiva entra em jogo aqui: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495, fazendo com que o valor delayacima seja 0, provocando esse manipulador para retornar imediatamente o NGX_DECLINEDque passa a solicitação para o próximo manipulador (e não o NGX_AGAINque efetivamente o enfileirará novamente para ser processado novamente).

Matt Whipple
fonte
1

Não entendi isso na primeira vez em que estava lendo a introdução em https://www.nginx.com/blog/rate-limiting-nginx/ .

Agora tenho certeza de que entendo e minha resposta é até agora a melhor. :)

Suponha: 10r/sestá definido, a capacidade máxima do servidor é, por exemplo, 10000r/squal é 10r/mse existe apenas 1 cliente no momento.

Então, aqui está a principal diferença entre 10r/s per IP burst=40 nodelaye 10r/s per IP burst=40.

insira a descrição da imagem aqui

Como o https://www.nginx.com/blog/rate-limiting-nginx/ documentou ( eu recomendo a leitura do artigo primeiro (exceto a seção Limitação de taxa em dois estágios )), esse comportamento corrige um problema. Qual?:

Em nosso exemplo, o vigésimo pacote na fila aguarda 2 segundos para ser encaminhado; nesse momento, uma resposta a ele pode não ser mais útil para o cliente.

Verifique o rascunho que fiz, a 40thsolicitação obtém resposta às 1senquanto a outra 40thobtém resposta às 4s.

Isso pode fazer o melhor uso possível da capacidade do servidor: envia respostas o mais rápido possível, mantendo a x r/srestrição a um determinado cliente / IP.

Mas também há custo aqui. O custo será:

Se você tem muitos clientes na fila do servidor, digamos cliente A, Be C.

Sem nodelay, os pedidos são atendidos em uma ordem semelhante a ABCABCABC.
Com nodelay, é mais provável que o pedido seja AAABBBCCC.


Gostaria de resumir o artigo https://www.nginx.com/blog/rate-limiting-nginx/ aqui.

Acima de tudo, a configuração mais importante é x r/s.

  1. x r/s somente solicitações em excesso são rejeitadas imediatamente.

  2. x r/s+ burst, pedidos em excesso estão na fila.

1.vs 2., o custo é que, no lado do cliente, as solicitações na fila aproveitam as chances de solicitações posteriores que terão a chance de serem atendidas.

Por exemplo, 10r/s burst=20vs 10r/s, a 11thsolicitação deve ser rejeitada imediatamente sob a última condição, mas agora está na fila e será atendida. A 11thsolicitação aproveita a 21thchance da solicitação.

  1. x r/s+ burst+ nodelay, já explicado.

PS A seção Limitação da taxa em dois estágios do artigo é muito confusa. Eu não entendo, mas isso não parece importar.

Por exemplo:

Com essa configuração, um cliente que faz um fluxo contínuo de solicitações a 8 r / s apresenta o seguinte comportamento.

8 r / s? seriamente? Há 17 pedidos dentro de 3 segundos mostrados na imagem, 17/3 = 8?

Rick
fonte