Como o NGINX processa uma requisição?

Rodrigo Vieira
OperacionalTI
Published in
3 min readJan 21, 2018

Quando temos que configurar diversos sites ou várias aplicações web no mesmo servidor nginx, é comum uma dose de incerteza ou até uma certa confusão na hora de configurar os Virtual Hosts ou server blocks na nomenclatura no nginx.

Partindo do princípio que temos a seguinte configuração:

server {
listen 80;
server_name .empresa1.com;
...
}
server {
listen 80;
server_name .empresa2.com;
...
}
server {
listen 80;
server_name .empresa3.com;
...
}
server {
listen 127.0.0.1:80;
server_name localhost;
...
}

Os parâmetros listen são convertidos internamente para sua forma completa: [ip]:[port]. Nas configurações acima: 0.0.0.0:80. Caso somente o endereço IP seja informado, 80 será utilizado como padrão para a porta.

Vamos analisar qual o comportamento do nginx ao receber uma requisição para http://www.empresa1.com, http://localhost e http://empresax.com.

Nota:
server_name .exemplo.com; é o mesmo que server_name exemplo.com *.exemplo.com;.

1. Análise do parâmetro "listen"

O nginx irá comparar o endereço IP e a porta da requisição com os parâmetros listen, selecionando os que se enquadrarem.

Se for realizada uma requisição para http://localhost então somente o quarto e último bloco será escolhido para atender a requisição. Já que o endereço IP e a porta da requisição serão respectivamente 127.0.0.1 e 80, casando com os valores informados no parâmetro listen do último bloco.

No entanto, caso a requisição tenha ocorrido por qualquer outro endereço IP, mas ainda na porta 80, os três primeiros blocos serão selecionados como potenciais blocos para atenderem a requisição. Nessa situação, quando mais de um bloco server é selecionado, o nginx fará uma segunda análise. Veja a seguir.

2. Análise do parâmetro "server_name"

O parâmetro server_name só é analisado qando vários blocos server forem selecionados como potenciais blocos para atender uma requisição. Nessa etapa o nginx compara o conteúdo do parâmetro Host, informado no cabeçalho da requisição HTTP, com o valor do parâmetro server_name de cada bloco server, selecionando o primeiro bloco que atender a esta condição.

Detalhes importantes

Blocos com o mesmo valor em listen e server_name
Se múltiplos blocos server possuírem o mesmo valor no parâmetro listen, bem como o mesmo conteúdo no parâmetros server_name apenas o primeiro será levado em consideração. Os demais serão responsáveis pela seguinte mensagem de alerta durante a inicialização do nginx:

nginx: [warn] conflicting server name “.empresarepetida.com” on 0.0.0.0:80, ignored

Requisição para um Host desconhecido
Uma requisição para um Host que não case com nenhum dos valores informados em server_name, será atendida pelo primeiro bloco server que case com o listen .

Por exemplo, uma requisição para http://www.empresax.com, que caia nesse servidor, será atendida pelo primeiro bloco (empresa1). Podemos contornar essa regra especificando o bloco padrão através da diretiva default_server no final do parâmetro listen do bloco desejado:

server {
listen 80;
server_name .empresa1.com;
...
}
server {
listen 80;
server_name .empresa2.com;
...
}
server {
listen 80 default_server;
server_name .empresa3.com;
...
}

Com isso, o bloco "empresa3" será responsável por atender a requisição a um Host desconhecido.

Nota:
É possível definir um default_server para cada grupo de blocos que tenham o mesmo valor no parâmetro listen.

Concluindo

Aprendemos como o nginx escolhe o bloco server para o qual a requisição http será encaminhada, dependendo dos valores dos parâmetros listen e server_name. No entanto, dentro de cada bloco server podemos ter diversos blocos location, onde a URI será comparada para determinar exatamente como a requisição será processada.

No próximo post vou detalhar as variações mais comuns para o parâmetro location. Fique antenado, siga o perfil nas redes sociais.

--

--