Como o NGINX processa uma requisição?
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 queserver_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 umdefault_server
para cada grupo de blocos que tenham o mesmo valor no parâmetrolisten
.
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.