Ajustando o número de processos

O primeiro passo é verificar se está sendo usado o módulo mpm-prefork (usado por default na maioria das distribuições) ou o módulo mpm-worker, já que ambos são configurados em seções diferentes do arquivo.

No caso das distribuições derivadas do Debian, as duas versões são disponibilizadas através de pacotes separados, de forma que você precisa apenas verificar qual dois dois está instalado, usando o comando “dpkg -l | grep apache”. Ele retornará uma lista como:

# dpkg -l | grep apache

ii apache2 2.2.3-4+etch4 Next generation, scalable, extendable web se
ii apache2-mpm-prefork 2.2.3-4+etch4 Traditional model for Apache HTTPD 2.1
ii apache2-utils 2.2.3-4+etch4 utility programs for webservers
ii apache2.2-common 2.2.3-4+etch4 Next generation, scalable, exten
ii libapache2-mod-fcgid 1.10-2 an alternative module compat with mod_fastcg
ii libapache2-mod-php5 5.2.0-8+etch11 server-side, HTML-embedded scri

No exemplo, podemos ver que está sendo usado o pacote “apache2-mpm-prefork”, que é justamente a versão usada por padrão.

O mpm-prefork é a versão tradicional do Apache, onde cada instância inicia um único thread e atende a uma única requisição por vez, isolando o processamento de cada página servida. Isso torna a operação do servidor mais estável e menos vulnerável a módulos ou páginas mal escritas, mas, em compensação, consome um pouco mais de memória RAM que o mpm-worker, onde cada instância do Apache pode abrir vários threads, de acordo com a necessidade.

Para pequenos servidores, onde você não precise necessariamente extrair cada gota de desempenho do servidor, o mpm-prefork é a escolha mais segura, mas em casos em que o servidor precise operar no limite, você pode realizar testes com o mpm-worker de forma a avaliar se a redução no consumo de memória é significativa.

Voltando à configuração, o número de instâncias abertas (ao usar o mpm-prefork) é determinada pela seção abaixo dentro do arquivo “/etc/apache2/apache2.conf“:

# prefork MPM
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

A opção “StartServers” determina o número padrão de instâncias do Apache que ficarão carregadas na memória, respondendo a requisições. Cada instância ocupa cerca de 7 MB de memória (variando de acordo com as opções de compilação usadas ao gerar o pacote e os módulos carregados), de forma que 5 instâncias consomem cerca de 35 MB de memória do servidor.

Além das instâncias principais, temos instâncias “reservas” (spares), que ficam disponíveis para absorver rapidamente picos de acesso, sem que o Apache tenha que perder tempo carregando mais instâncias para só depois começar a responder às requisições. As opções “MinSpareServers” e “MaxSpareServers” determinam o número mínimo e máximo de “reservas”, sendo que o número real flutua entre os dois parâmetros, de acordo com a demanda.

A opção “MaxClients” é a parede de concreto, o número máximo de conexões simultâneas que o Apache aceita manter abertas, independentemente da demanda. Quando esse número é atingido, o acesso ao site fica cada vez mais lento, pois cada novo visitante “entra na fila” e precisa esperar que uma das instâncias do Apache fique livre, antes de conseguir carregar cada página.

Essa configuração default do Apache é adequada a um site de baixa demanda, onde o servidor passa a maior parte do tempo atendendo a um pequeno volume de requisições simultâneas, mas recebe picos de tráfego esporadicamente. Por padrão, o servidor carregará apenas 5 processos, manterá mais 5 a 10 spares ativos e poderá carregar mais instâncias conforme necessário, até o limite máximo de 150 instâncias permitidas.

Para um servidor dedicado, que hospede um site com muitas visitas, é interessante ajustar estes valores de acordo com a demanda. Uma forma fácil de verificar o status do servidor é ativar a diretiva “server-status” dentro do arquivo “/etc/apache2/apache2.conf”. Adicione as linhas abaixo no final do arquivo:

<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 200.234.23.233
# (onde o 200.234.23.233 é o IP de onde o relatório será acessado)
</Location>

Ative a configuração usando o comando “/etc/init.d/apache2 reload”. A partir daí, você pode ver um instantâneo do status do servidor acessando a pasta “server-status”, como em “http://www.gdhn.com.br/server-status“, a partir do navegador.

A oitava linha indica o número de instâncias abertas, como em:

8 requests currently being processed, 5 idle workers

Nesse exemplo temos 8 conexões abertas e 5 instâncias reservas do Apache abertas, prontas para receber novas conexões. A velocidade do acesso ao site está normal. Mas, o que acontece no caso de um pico de acesso, com mais do que 150 acessos simultâneos? Na configuração padrão você teria:

150 requests currently being processed, 0 idle workers

Ou seja, o Apache responde às primeiras 150 conexões e coloca as demais na fila, fazendo com que os visitantes precisem esperar até que algum dos processos abertos termine de atender o visitante anterior antes de servirem a requisição. Nesse ponto o acesso ao site começa a ficar lento, com as páginas demorando mais e mais para começarem a ser carregadas. Em casos mais extremos, o tempo de espera poderia ser tamanho que o site ficaria virtualmente fora do ar. É o que muitas vezes acontece com links publicados em sites muito acessados, como o slashdot.org.

Isso pode ser minimizado de duas formas. A primeira é aumentando o número de instâncias ativas do Apache (de forma que o servidor tenha instâncias suficientes para atender a todas as requisições sem precisar abrir novos processos) e aumentando o valor configurado na opção “MaxClients”, de forma que o servidor possa atender a um volume maior de requisições nos horários de pico.

Os valores ideais variam de acordo com o volume de memória disponível no servidor e a quantidade de memória usada por cada processo do Apache. Comece usando o comando “ps -ylC apache2 –sort:rss” (no Debian/Ubuntu) ou “ps -ylC httpd –sort:rss” (no Fedora/CentOS) para verificar o volume de memória usado por cada instância do Apache:

# ps -ylC apache2 –sort:rss

O comando exibe uma linha para cada processo do Apache ativo, de forma que a lista pode ser longa. O volume de memória gasto por cada um (em kbytes) é mostrado na oitava coluna. Descartando as primeiras e as últimas linhas, você tem uma boa aproximação dos valores médios, como em:

S 33 17530 16102 0 78 0 6008 5038 341548 ? 00:00:00 apache2
S 33 17491 16102 0 75 0 6036 5036 354540 ? 00:00:00 apache2
S 33 17529 16102 0 75 0 6036 5038 357283 ? 00:00:00 apache2
S 33 17472 16102 0 75 0 6044 5038 359161 ? 00:00:00 apache2
S 33 17438 16102 0 75 0 6056 5036 351130 ? 00:00:00 apache2

Veja que no exemplo cada processo consome aproximadamente 6 MB de memória RAM. Estes valores não devem ser levados ao pé da letra, pois o ps não leva em conta as áreas de memória compartilhadas entre os processos (como vimos no capítulo 1), de forma que na prática o consumo total é sempre um pouco mais baixo. De qualquer forma, estes são os melhores números que temos.

O próximo passo é verificar quanto os demais serviços ativos no servidor (MySQL, servidor de e-mails, etc.) consomem, de forma a ter uma estimativa de quanta memória está disponível para uso do Apache. Uma forma simples de fazer isso é desativar temporariamente o Apache (/etc/init.d/apache2 stop) e usar o comando “free” para ver a memória disponível, como em:

# free

total used free shared buffers cached
Mem: 127132 124640 2492 0 40732 45236
-/+ buffers/cache: 35804 91328
Swap: 409616 48 409568

A linha “Mem” mostra o total de memória usada, incluindo o cache de disco. Ela sempre mostra que quase toda a memória está ocupada, pois é normal que o sistema utilize a memória disponível para fazer cache de disco. O que realmente nos interessa é a segunda linha (-/+ buffers/cache), que no exemplo mostra que o servidor possui cerca de 90 MB de memória disponível (nesse exemplo estou usando um VPS com apenas 128 MB de memória, que serve como exemplo de servidor com poucos recursos).

Se cada processo do Apache ocupa cerca de 6 MB de memória, significa que o servidor poderia manter de 15 a 18 instâncias carregadas na memória (levando em conta que o consumo real é sempre um pouco inferior ao mostrado pelo ps) antes de começar a usar um volume significativo de memória swap. Uma boa configuração nesse caso seria:

# prefork MPM
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 18
MaxRequestsPerChild 0
</IfModule>

Permitir que o Apache abra mais instâncias acabaria sendo contra produtivo, pois o uso de muita memória swap derrubaria o desempenho do servidor, fazendo com que cada instância demorasse mais para processar cada página. Com isso, o número total de páginas servidas acabaria sendo menor do que usando apenas 18 processos.

No caso de um servidor com 1 GB de memória RAM, por outro lado, provavelmente teríamos 900 MB ou mais de memória disponível para o Apache, de forma que uma configuração mais adequada seria:

# prefork MPM
<IfModule mpm_prefork_module>
StartServers 25
MinSpareServers 25
MaxSpareServers 50
MaxClients 200
MaxRequestsPerChild 0
</IfModule>

Com isso, teríamos 25 processos “fixos” do Apache, complementados por mais 25 a 50 spares, número que pode crescer até um máximo de 200 processos simultâneos nos horários de pico. A partir daí, você poderia monitorar o volume de memória livre no servidor (através do comando “free”) e o volume de acessos através da página de estatísticas e ajustar as opções “StartServers” e “MinSpareServers” de acordo com o número médio de acessos simultâneos, de forma que o número de processos do Apache e de spares disponíveis seja sempre um pouco maior do que o número médio de conexões ao servidor:

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X