Por que você configuraria o MaxKeepAliveRequests para algo além de ilimitado?

11

O Apache KeepAliveTimeoutexiste para fechar uma conexão keep-alive se uma nova solicitação não for emitida dentro de um determinado período de tempo. Desde que o usuário não feche seu navegador / guia, esse tempo limite (geralmente de 5 a 15 segundos) é o que acaba fechando a maioria das conexões keep-alive e evita que os recursos do servidor sejam desperdiçados mantendo-as indefinidamente.

Agora a MaxKeepAliveRequestsdiretiva coloca um limite no número de solicitações HTTP que uma única conexão TCP (deixada em aberto devido a KeepAlive) atenderá. Definir isso para 0significa que um número ilimitado de solicitações é permitido.

Por que você configuraria isso para algo além de "ilimitado"? Desde que um cliente ainda esteja solicitando ativamente, que mal há em deixá-lo acontecer na mesma conexão keep-alive? Quando o limite é atingido, os pedidos ainda chegam, apenas em uma nova conexão.

Do meu ponto de vista, não faz sentido limitar isso. o que estou perdendo?

Jonathon Reinhart
fonte

Respostas:

4

Basicamente, porque o Apache não foi construído para isso. O problema é o uso de memória do servidor. Em muitas configurações, a geração de conteúdo é feita no mesmo processo que a entrega de conteúdo, portanto, cada processo aumenta para o tamanho da maior coisa que ele lida. Imagine um processo expandido para 64 MB por causa de um script php pesado, depois esse processo inchado sentado e servindo arquivos estáticos. Agora multiplique por 100. Além disso, se houver vazamento de memória em qualquer lugar, os processos crescerão sem limite.

As configurações de manutenção da atividade devem ser balanceadas com base no tipo de seu conteúdo e no seu tráfego. Geralmente, a configuração ideal tem MaxKeepAliveRequests alto (100-500) e KeepAliveTimeout baixo (2-5) para liberá-los rapidamente.

Dirigível
fonte
2

Eu sei que essa é uma pergunta antiga, mas venho fazendo alguma depuração e parece que (e isso não é verdade apenas para o Apache) MaxKeepAliveRequestsfunciona independentemente KeepAliveTimeout.

Ou seja, a diretiva timeout conta apenas para conexões persistentes inativas (sem leituras ou gravações) - se você continuar solicitando abaixo do tempo limite, poderá virtualmente fazer uma quantidade ilimitada de solicitações na mesma conexão.

Isso pode não ser bom por alguns motivos, incluindo conexões tcp de execução longa sendo eliminadas aleatoriamente? De qualquer forma, os clientes http não são tão estúpidos e podem lidar MaxKeepAliveRequestsmuito bem com uma configuração "baixa" ; por exemplo, é relativamente fácil na linguagem de programação detectar se uma conexão tcp foi fechada pelo servidor e, portanto, se reconectando a ela novamente. Além disso, a maioria dos clientes http terá limites por conta própria (por exemplo, os navegadores fechariam uma conexão keep-alive após 300 segundos ou mais).

lifeofguenter
fonte
1

Uma razão seria para o balanceamento de carga. Depois que uma conexão keep-alive ou persistente http 1.1 for estabelecida, o balanceador de carga não a moverá para um novo host até que ela seja fechada. Se você tem um cliente fazendo um grande número de solicitações pela conexão única, pode não conseguir um bom equilíbrio entre os servidores.

dtauzell
fonte
Mas por que isso importa? Para mim, parece indesejável espalhar a conexão de um único usuário por vários servidores. O balanceamento de carga é para lidar com um grande número de usuários, não com conexões de um único usuário. De fato - se um único usuário estiver martelando um serviço, você prefere que ele seja confinado a um único servidor (onde eles efetivamente se limitariam a uma taxa).
Jonathon Reinhart
11
Bons pontos. Algumas reflexões: 1. qualquer outra pessoa nesse servidor também seria martelada. 2. Para balanceadores de carga que funcionam abaixo do nível HTTP: quando você tira um servidor do pool, ele não fecha a conexão HTTP existente. Isso torna um pouco mais difícil mover as pessoas para um servidor diferente apenas com o balanceador de carga. O motivo 2 é como cheguei a esta página enquanto pesquisava para ver o que as pessoas tinham a dizer sobre esse parâmetro.
dtauzell
11
Uma terceira razão: se o servidor / aplicativo entrar em um estado ruim e estiver com erros, a fixação poderá causar erros em todos os pedidos até que a situação seja corrigida, enquanto que se você limitar quantos eles têm chance de se equilibrar em um novo servidor .
Dtauzell
Eu não encontrei um balanceador de carga que funciona assim. Um balanceador de carga geralmente possui um parâmetro de "aderência" que define se todas as solicitações do cliente (determinadas por IP, por exemplo) na sessão atual devem ser roteadas para o mesmo fluxo ascendente ou distribuídas entre fluxos ascendentes. Essa opção é útil depende do aplicativo que está sendo executado nas correntes ascendentes
Manuel
1

Em parte, para impedir que um único usuário monopolize todos os slots de conexão. Sem limite, um cliente mal-intencionado ou mal escrito pode assumir todas as conexões disponíveis e mantê-las para sempre. Essa não é uma grande mitigação para isso, no entanto, comparada a algo como um limite de conexão por IP.

Principalmente balanceamento de carga, mas especificamente com relação à manutenção. Se você deseja colocar um servidor offline, reduza-o para 0 conexões, mas permita que as conexões existentes sejam concluídas por um certo período de tempo. A limitação do número de solicitações de manutenção de atividade significa que, eventualmente, os usuários criarão normalmente uma nova conexão e serão movidos para um novo servidor de back-end. Provavelmente, alguma maneira de sinalizar para o servidor que ele deveria parar de aceitar o keepalives por completo durante o processo de drenagem seria ainda melhor, mas até onde eu sei, esse recurso não existe.

Elliott
fonte