Nginx

De Biblioteca Unix

Conteúdo

Nginx

Objetivo

O objetivo é aumentar a performance de sites na Internet que estejam com servidores como o Apache2.2 no limite da performance, ou seja, o servidor está alcançando picos de 5/10 de load average e o número de filhos do Apache não para de consumir a memória do servidor. Todos os parâmetros de tunning foram utilizados, mas mesmo assim, seu servidor parece não aguentar o número de requisições.

Acabamos detectando que a melhor solução foi abordar o mesmo problema de outra forma, no caso, utilizamos o Nginx para responder pelo conteúdo estático do nosso site e deixamos a parte dinâmica para o Apache2.2.

Ambiente Proposto

Nós vamos utilizar um site público na Internet configurado com o Apache2.2 como veremos e utilizaremos o Nginx como proxy para o conteúdo estático.

  • Servidor executando o Apache2.2 na porta 80 (Directory Root: /var/www)
  • Divisão bem definida entre o conteúdo estático e dinâmico no site
  • No nosso caso, conteúdo dinâmico em PHP (poderia ser outro)

com isso podemos configurar nosso ambiente para incrementar a performance.

Debian Squeeze 6.0

Instalando os Pacotes necessários

No Debian Squeeze já temos o pacote do Nginx, vamos instalá-lo:

# apt-get install nginx

ele não vai inicializar, pois o Apache2.2 está configurado nesta porta.

Configurações Básicas

O Nginx por padrão vem configurado para escutar a porta 80 e servir o conteúdo armazenado no diretório '/var/www, basta iniciá-lo para começar a utilizar:

# /etc/init.d/nginx start

pronto, ele vai estar funcionando corretamente.

Configurando o Nginx como Proxy para o Apache2.2

A idéia geral é a seguinte:

  1. O cliente requisita o site na porta 80 (esta requisição será feita para o Nginx)
  2. O Nginx vai analisar se o conteúdo é estático ou dinâmico
    1. Se for estático, ele mesmo vai atender a requisição
    2. Se for estático, ele vai encaminhar por proxy a conexão para o Apache2.2

Vamos as configurações, primeiro vamos fazer com que o Apache2.2 passe a escutar em outra porta, por exemplo a 8080:

# vim /etc/apache2/ports.conf
NameVirtualHost *:8080
Listen 8080

<IfModule mod_ssl.c>
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>

A porta estava configurada para 80 e trocamos para 8080, agora devemos fazer o mesmo no domínio virtual do site que estamos configurando:

# vim /etc/apache2/sites-enabled/site-da-empresa
<VirtualHost *:8080>
       ServerAdmin webmaster@empresa.com.br
       ServerName www.empresa.com.br
       DocumentRoot /var/www/
       ... 
</VirtualHost>

Agora vamos alterar o Nginx para servir o conteúdo separando o que é estático do que é dinâmico:

# vim /etc/nginx/sites-enabled/default
upstream servers  {
   ip_hash;
   server 127.0.0.1:8080;
   server srv2.exemplo.com.br;
}

server {
       listen   80; ## listen for ipv4
       listen   [::]:80 default ipv6only=on; ## listen for ipv6
       server_name  www.empresa.com.br;
       access_log  /var/log/nginx/d-a.proxy.log;

       # Servir diretamente os diretórios:  /images/ + /css/ + /js/
       location ^~ /(images|css|js) {
               root   /var/www/;
               access_log  /var/log/nginx/d-a.direct.log ;
       }

       # Servir diretamente arquivos com extensão:
       location ~* \.(js|css|rdf|xml|ico|txt|gif|jpg|png|jpeg)$ {
               root   /var/www/;
               access_log  /var/log/nginx/d-a.direct.log ;
       }

       # Para qualquer outra requisição não servida anteriormente, enviar para o Pool servers.
       location / {
               proxy_pass         http://servers;
               proxy_redirect     off;
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
               client_max_body_size       10m;
               client_body_buffer_size    128k;
               proxy_connect_timeout      90;
               proxy_send_timeout         90;
               proxy_read_timeout         90;
               proxy_buffer_size          4k;
               proxy_buffers              4 32k;
               proxy_busy_buffers_size    64k;
               proxy_temp_file_write_size 64k;
       }
}

Algumas notas importantes: um pool de servidores foi criado e chamado de servers, onde o parâmetro ip_hash garante que cada cliente vai estar conectado em um dos servidores a não ser que ele fique indisponível, para garantir a sessão em sistemas em PHP, por exemplo. Se o seu sistema não tem sessão, então utilizar parâmetros como weight e fail_timeout seja uma opção mais interessante para garantir redundância e balanceamento. A utilização de mais de um servidor é opcional, poderíamos ter somente utilizado o servidor do Apache2.2 executando em localhost.

Agora basta reinicializar o servidor Apache2.2:

# /etc/init.d/apache2 restart

e logo em seguida o Nginx:

# /etc/init.d/nginx start

pronto, o Nginx vai começar a tratar o conteúdo estático e vai repassar somente o dinâmico, você pode ver isso nos logs:

  • d-a.proxy.log : conteúdo repassado para o Apache2.2
  • d-a.direct.log: conteúdo respondido diretamente pelo Nginx

A utilização dos servidores Apache2.2 no nosso ambiente reduziu drasticamente e a solução está rodando estável a dias. --Brivaldo 17h58min de 7 de março de 2011 (AMT)

Ferramentas pessoais