O NGINX (Engine X) é um Software Open Source que tem como funcionalidade principal atender requisições HTTP na web.
Porém ele não serve somente para isso, não é atoa que ele é o webserver mais utilizado na internet. Além de atender requisições HTTP de forma excepcional existe uma serie de recursos que o torna cada vez mais interessante, sendo elas: proxy reverso, armazenamento em cache, balanceamento de carga, streaming de mídia e muitas vezes utilizado para funcionar como um servidor proxy para e-mail (IMAP, POP3 e SMTP). Mais a frente falo um pouco sobre cada uma dessas funcionalidades do nginx e em quais contextos são mais utilizadas.
História por trás
O NGINX foi escrito originalmente para resolver a dificuldade que os servidores web existentes enfrentavam em lidar com grandes números (os 10K ) de conexões simultâneas.
Em 2004 seu fundador Igor Sysoev após ver seu uso crescer exponencialmente, decide a abrir o código do projeto e cria a NGINX, Inc. para dar suporte ao desenvolvimento contínuo do NGINX e comercializar o NGINX Plus como um produto comercial para clientes corporativos.
Diferenças entre Apache e NGINX
O NGINX supera o Apache e alguns outros servidores em benchmarks que medem o desempenho de servidores web, Desde o lançamento do NGINX. No entanto, os sites evoluiram de páginas HTML estáticas para conteúdo dinâmico. O NGINX cresceu junto com ele e agora suporta todos os componentes da Web "moderna", incluindo WebSocket, HTTP/2, gRPC e streaming de vários formatos de vídeo HDS, HLS entre outros.
Além da alta customização do nginx e suporte de novos componentes da web, o que se da a sua alta performace em relação ao apache é a sua arquitetura que dita a forma na qual o webserver atende suas requisições, por sua vez o apache é "process-based server" (arquitetura baseada em processos) em que cada solicitação de conexão é tratada por um único processo. A maneira como geralmente funciona é um processo pai do servidor recebe solicitações de conexão e, quando isso acontece, ele cria (gera) um processo filho para lidar com isso. Quando outra solicitação chega, o processo pai gera um novo processo filho para lidar com a nova solicitação e assim por diante.
Porém, isso tudo acaba gerando um custo de processamento absurdo, pois, quanto mais solicitações e conexões abertas, mais recursos computacionais serão gastos.
Já no NGINX temos um outro tipo de arquitetura, uma arquitetura assíncrona e “event‑driven architecture” (Arquitetura orientada a eventos).
Significa que threads iguais são comandadas por um process_worker, e cada process_worker contém unidades menores chamadas worker_connections. Esta unidade inteira é responsável de cuidar das solicitações. worker_connections levam as solicitações até um process_worker, que por sua vez as envia para o processo master. Finalmente o processo master fornece o resultado da solicitação.
de forma simples: existe um worker principal e diversos workers menores que recebem requisiçoes, porem cada worker é assincrono e capaz de receber mais de uma requisição, ou seja, enquanto ele está devolvendo um arquivo estático de CSS o mesmo worker já está atendendo uma nova requisição e por ai vai...
Um detalhe: Os workers geralmente são criados de acordo com a quantidade de núcleos da CPU. Porém pode ser "setado" no arquivo de configuração do nginx.
Caso tenha acabado de fazer a instalação do nginx vai estar assim:
worker_processes: auto;
Desta forma ele está configurado para criar workers de acordo com a quantidade de núcleos da CPU.
Um único worker é capaz "cuidar" de até 1024 solicitações similares.
Proxy Reverso
Quande se fala de NGINX sempre é citado o famoso Proxy reverso, mas afinal, oque seria isso?
Confesso que quando me explicaram o que era fiquei uns 2 minutos com cara de paisagem tentando entender
Bom, para entendermos o proxy reverso primeiro precisamos elucidar o conceito de proxy. Proxy é um servidor que atua como intermediário entre o usuário e a internet, recebendo as requisições e repassando. Geralmente muito utilizado dentro de empresas para bloquear acesso de sites e outros conteúdos.
Tendo essa difinição podemos dizer que um proxy reverso é um servidor intermediário que fica ao lado do servidor e não mais ao lado do cliente recebendo as requisições e redirecionando para outros servidores/serviços corretos.
Um exemplo bem simples:
server {
listen 80;
server_name localhost;
location / {
root /users/juan/dev/nginx;
index index.html
}
location ~ /.php$ {
proxy_pass http://localhost:8000;
}
}
server - é um bloco designado a escrever as configurações de um servidor dentro da sua configuração. Você pode ter vários deles, cada um atendendo em uma porta diferente. Você pode expor um servidor para o mundo e ter outro interno, sem cache, por exemplo, ou até driblando a autenticação, por exemplo.
listen - aqui você define em qual porta seu servidor vai aceitar as conexões.
-
location - é a diretiva usada para definir as rotas. Elas são bem poderosas. Aceitam expressões regulares, é possível capturar as variáveis e usá-las na configuração. O sistema de location, também, conta com diferentes tipos de match.
- Sem modificador, o match é feito pelo começo da URI.
- = é um match exato.
- ~ é um match com expressão regular.
Nesse caso o nginx foi configurado para redirecionar toda requisição que tenha PHP para um serviço especifico, que vai executar a lógica e processar as informações, caso seja uma requisição de algum arquivo estático como uma página em html, o servidor prontamente devolverá sem precisar enviar requisição ao servidor PHP. Assim dando mais dinâmica a todo o processo.
LoadBalancing
A maioria das vezes uma aplicação em produção tem mais de um servidor para servir ela, isso se dá pois os servidores possuem recursos finitos (CPU,Disco etc.) para atender multiplas requisições. E não é apenas sobre isso. E se o servidor sofrer uma falha de hardware? Ou até alguma falha de rede? Inúmeros motivos podem fazer sua aplicação ficar sem um fallback pra esses casos.
Nesses casos utilizamos o Upstream onde denominamos servidores para balancear a aplicação.
upstream servicos {
server localhost:8001;
server localhost:8002;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://servicos;
}
}
Como não estamos utilizando algoritimos de balanceamento como Round robin, IP hash etc. O nosso servidor apenas vai intercalar as requisiçõe entre os serviços, ou seja, 50% das requisções vai para o localhost:8001 e 50% para o localhost:8002.
Esse é um exemplo básico, mas pode ser explorado de várias maneiras assim mitigando riscos de ter sua aplicação fora do ar.
Considerações Finais
Objetivo desse Post é apenas dar uma pincelada sobre o webserver mais rápido do mercado e mostrar algumas caracteristicas que lhe deram esse título. No próximo Post teremos exemplos aplicados e mostrarei algumas outras funcionalidades como: Cache, Stream etc.
Top comments (2)
Excelente artigo, exposição clara e objetiva de ideias! Ótimo para dar base ao que o NGINX tem a oferecer!
Boa, ficou bem claro e explicativo. Fico aguardando ansiosamente a parte 2.