Apache logo

Como configurar o módulo mpm prefork para melhorar a performance do servidor web Apache

Ao concluir a instalação do seu servidor web Apache, pode ser interessante realizar alguns ajustes na sua configuração para obter um melhor desempenho ou adequá-lo às condições de hardware e de uso.
Neste post, vou mostrar como ajustar o mpm_prefork.conf do Apache.
apache-feather-logo-24colors
As informações contidas neste post foram testadas em um sistema operacional Debian 8.2 “jessie”, com o servidor web Apache 2.4 padrão da distribuição — e servem para Ubuntu 14.04 LTS (ou superior) também.
Outras diretivas e parâmetros de configuração, presentes no Apache, precisam ser incluídas no ato da compilação do software — e, portanto, não serão abordados neste texto.
Para saber a versão do seu servidor Apache, use o seguinte comando:

sudo apache2 -v
Server version: Apache/2.4.10 (Debian)
Server built:   Aug 28 2015 16:28:08

O que é o MPM prefork do Apache?

MPM é sigla para Multi-Processing Module ou Módulo de Processamento Múltiplo (em uma tradução livre).
É responsável pela implementação de um servidor web sob a “metodologia” non-threaded, em um servidor pre-forking, que lida com as requisições de modo similar ao do Apache 1.3. (Veja o quadro ao final deste texto)
É apropriado para sites que precisam evitar a criação de threads, para manter compatibilidade com bibliotecas non-thread-safe (PHP, por exemplo…).
O MPM é autorregulado, de modo que raramente é necessário ajustar diretivas de configuração.

O conteúdo do arquivo mpm_prefork.conf

Para ver o conteúdo do arquivo de configuração, tema deste artigo, use o comando cat.
O conteúdo do meu arquivo mpm_prefork.conf (tirando os comentários) é o que segue:

cat /etc/apache2/mods-enabled/mpm_prefork.conf
#
<IfModule mpm_prefork_module>
	StartServers			5
	MinSpareServers			5
	MaxSpareServers			10
	MaxRequestWorkers		150
	MaxConnectionsPerChild  	0
</IfModule>

Estes são os valores originais.
O significado de cada uma destas linhas de configuração é o que segue:

  • StartServers — número de processos do servidor para iniciar
  • MinSpareServers — quantidade mínima de processos do servidor a ser reservada
  • MaxSpareServers — quantidade máxima de processos do servidor a ser reservada
  • MaxRequestWorkers — número máximo de processos do servidor permitidos para iniciar.
    Em versões anteriores ao Apache 2.4, era chamado de MaxClients
  • MaxConnectionsPerChild — número máximo de requisições que um processo do servidor deve atender

Como funciona o MPM

Um único processo é responsável pelo lançamento dos processos filhos, que ouvem as conexões e as atendem, quando chegam.
O Apache sempre tenta manter vários processos do servidor em reserva, prontos a atender novas requisições — desta forma, economiza tempo para criar novos processos filhos (forking) para atender a novas requisições.
As diretivas StartServers, MinSpareServers, MaxSpareServers e MaxRequestWorkers controlam o modo como os processos pais criam novos processos filhos para servir às novas requisições.
Em geral, o Apache é bom em se autorregular em função da demanda, de modo que muitos administradores de sites não vão precisar ajustar estas diretivas.
Manter os valores padrão é o recomendado para a maioria, portanto.
Sites que precisam servir mais do que 256 requisições simultâneas, contudo, podem precisar aumentar o valor de MaxRequestWorkers.
Caso os recursos de memória sejam limitados, pode ser necessário reduzir este valor para prevenir que o servidor faça thrashing — ou seja, faça uso da memória swap em disco (o que vai ocasionar um problema severo de lentidão).

O mais importante é que o MaxRequestWorkers seja grande o suficiente para comportar a quantidade de requisições simultâneas que você espera receber.
Ao mesmo tempo, o valor desta diretiva deve ser pequeno o suficiente para assegurar que haja memória RAM física suficiente para todos os processos.

Enquanto o processo pai é costumeiramente iniciado como root (UNIX e GNU/Linux) para se conectar à porta 80, os processos filhos são iniciados pelo Apache com privilégios de usuário comum.
As diretivas de Usuário e Grupo são usados para ajustar os privilégios dos processos filhos do Apache — que só precisam estar habilitados a ler aquele conteúdo que será servido.
A diretiva MaxRequestsPerChild controla a frequencia com que o servidor recicla processos, matando os velhos e criando novos.

A diretiva StartServers

Este parâmetro ajusta o número de processos filhos que devem ser criados na inicialização do Apache.
Uma vez que este número é controlado dinamicamente, em função da carga de trabalho do servidor web, geralmente há poucas razões para alterar este número.

A diretiva MaxSpareServers

O valor padrão desta diretiva é 10, de acordo com a documentação oficial do Apache (link no final do texto).
Este parâmetro determina o número máximo de processos ociosos do servidor.
É denominado processo ocioso aquele que não esteja trabalhando com alguma requisição.
O processo pai vai ‘matar’ os processos filhos ociosos, assim que sua quantidade exceder o limite determinado em MaxSpareServers.
Ajustar este parâmetro só é necessário em sites muito ocupados.
Se você ajustar o valor deste parâmetro para um número igual ou menor do que o valor de MinSpareServers, o Apache irá automaticamente reajustá-lo para MinSpareServers + 1.

Ajustar os parâmetros MinSpareServers e MaxSpareServers para valores extremos é quase sempre uma idéia ruim.
Ao fazer isto, você adiciona ao servidor um excesso de carga de trabalho ou overhead, por que ele precisará terminar/iniciar, sem necessidade, os workers de reserva em execução no background.

A diretiva MinSpareServers

Esta variável ajusta o número desejado de processos filhos ociosos do servidor.
Como você já sabe, processo ocioso é aquele que não está lidando com alguma requisição.
Havendo menos destes processos do que a quantidade determinada em MinSpareServers, o processo pai irá iniciar a criação de novos processos filhos, a uma taxa máxima de 1 por segundo.

A diretiva MaxConnectionsPerChild

Delimita o número de conexões com que cada processo filho pode trabalhar individualmente.
Após atingir o valor definido em MaxConnectionsPerChild, o processo filho irá terminar (morrer).
Você pode ajustar o valor para 0 (zero), se quiser que o processo nunca expire.
Ao usar valores diferentes de 0, contudo, você vai limitar a quantidade de memória que cada processo poderá consumir em caso de vazamento acidental de memória.

Conclusão

Quando terminar de configurar estes parâmetros, não use o reload para reiniciar o Apache.
O certo é parar o servidor e, em seguida, iniciá-lo.
A razão disto é que nem todas as mudanças farão efeito até que você desligue o processo principal (inicial) do Apache.
No Debian, use o seguinte comando para isto:

sudo service apache2 stop
sudo service apache2 start
sudo service apache2 status

O resultado do último comando deve ser parecido com o que segue:

● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2)
   Active: active (running) since Sex 2015-12-04 10:00:49 BRT; 1min 7s ago
  Process: 7399 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS)
  Process: 6561 ExecReload=/etc/init.d/apache2 reload (code=exited, status=0/SUCCESS)
  Process: 7451 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/apache2.service
           ├─7465 /usr/sbin/apache2 -k start
           ├─7469 /usr/sbin/apache2 -k start
           ├─7470 /usr/sbin/apache2 -k start
           ├─7471 /usr/sbin/apache2 -k start
           ├─7472 /usr/sbin/apache2 -k start
           ├─7473 /usr/sbin/apache2 -k start
           └─7474 /usr/sbin/apache2 -k start

Dez 04 10:00:48 ultra apache2[7451]: Starting web server: apache2AH00558:...e
Dez 04 10:00:49 ultra apache2[7451]: .
Hint: Some lines were ellipsized, use -l to show in full.

O que são Non-threaded e Pre-fork no Apache?

Servidores web diferentes, tem diversas técnicas de manipulação das requisições HTTP em paralelo.
Uma das metodologias mais populares envolve o uso de threads — ou seja, o servidor web vai criar/dedicar uma única thread a cada nova requisição recebida.
O servidor web Apache suporta múltiplos modelos de tratamento de requisições — um deles, o MPM, usa threads.
Além disto, suporta um outro modelo chamado prefork MPM, que usa processos — no qual o servidor web cria/dedica um único processo a cada nova requisição.

Referências:

https://httpd.apache.org/docs/2.2/mod/prefork.html.
http://askubuntu.com/questions/488044/neither-prefork-nor-worker-settings-are-found-in-etc-apache2-apache2-conf-why.
http://wiki.zarafa.com/index.php/Apache_tuning.
http://stackoverflow.com/questions/1623914/what-is-thread-safe-or-non-thread-safe-in-php.
http://serverfault.com/questions/684424/how-to-tune-apache-on-ubuntu-14-04-server.

Publicado por

Elias Praciano

Autor de tecnologia (livre, de preferência), apaixonado por programação e astronomia. Fã de séries, como "Rick and Morty" e "BoJack Horseman". Me siga no Twitter e vamos trocar ideias!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *