Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 21, 2022 12:25 pm GMT

Uma introduo ao NGINX

Volta e meia leio de algumas pessoas que NGINX (engine X) complicado. Eu no vou mentir: no algo simples de se entender e usar de primeira. Primeiramente, no fcil entender qual a finalidade dele. um servidor, mas o que ele faz? Como usado?

NGINX um servidor que pode ser usado de diversas maneiras, tais como: load balancer (balancear requests para os servidores de aplicao), proxy reverso (receber um request da internet e repassar para outro servidor ou servio) e uma das capacidades mais fantsticas do NGINX, na minha opinio, sua finalidade como cache.

Uma generosa parte da internet roda sobre NGINX e alguns segmentos bem importantes usam ele como principal servidor, como plataformas de streaming, aplicaes de larga escala tais como lojas, redes sociais e, tambm, usado como base de muitas CDNs.

Porque usar NGINX?

Talvez voc j tenha se perguntado: porque eu deveria usar NGINX? No mais fcil s apontar o DNS para vrios IPs?
Isso possvel, mas voc no vai ter a robustez de apontar seu DNS para um load balancer que pode balancear seus requests de uma forma mais inteligente, com o apoio de healthcheck caso seus servidores de aplicao no estejam respondendo e de algoritmos de balanceamento, implementando o modelo correto de distribuio de requests.

Se voc j compreende o bsico e apenas quer olhar uma configurao escrita com containers rodando uma soluo, o repositrio de exemplo. Ele est dividido em tags mostrando a evoluo das partes do texto.

Vamos criar nossa primeira configurao, bem bsica, com apenas uma rota que sempre retorna 200:

worker_processes auto;events {  worker_connections 1024;}http {  server {    listen 80;    location / {      return 200;    }  }}

Vamos usar Docker com a ajuda do Docker Compose:

services:  nginx:    image: nginx:alpine    volumes:      - ./nginx.conf:/etc/nginx/nginx.conf    ports:      - "8080:80"

Testando nossa rota:

curl -v http://localhost:8080< HTTP/1.1 200 OK< Server: nginx/1.21.6< Content-Type: text/plain< Content-Length: 0< Connection: keep-alive

Nossa rota funcionou. Ela retorna 200 como esperado.

Vamos entender o que essa configurao faz, focando apenas no bloco http. O bloco http chamado de contexto, assim como o events, e ambos est em um contexto chamado main

  • server - um bloco designado a escrever as configuraes de um servidor dentro da sua configurao. Voc pode ter vrios 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 autenticao, por exemplo.
  • listen - aqui voc define em qual porta seu servidor vai aceitar as conexes. Note que o docker-compose.yml exporta a 80 como 8080 para o host, por isso o request feito na 8080 (porta 80 do container).
  • location - a diretiva usada para definir as rotas. Elas so bem poderosas. Aceitam expresses regulares, possvel capturar as variveis e us-las na configurao. O sistema de location, tambm, conta com diferentes tipos de match.

    • Sem modificador, o match feito pelo comeo da URI
    • = um match exato
    • ~ um match com expresso regular

Esses so os modificadores que mais usei at hoje.

Nossa location faz match com qualquer URI que comece com /, ou seja, qualquer uma como /compras, /produtos/lista, etc.

Podemos adicionar uma nova location com match exato.

location = /teste {  return 200 "teste route";}location / {  return 200;}

Agora podemos notar que a rota /teste tem um body sendo respondido.

curl -v http://localhost:8080/teste< HTTP/1.1 200 OK< Server: nginx/1.21.6< Content-Type: text/plain< Content-Length: 11< Connection: keep-aliveteste route

Vimos um pouco do bsico da configurao, agora hora de fazermos algo mais avanado.

Usando como proxy reverso

Uma definio simplista de proxy reverso um request que voc faz em algum endereo da interno, como por exemplo http://meusite.com.br/minhaloja/produtos/1 e no sabendo pra onde exatamente esse request vai ser processado. E, aps processado, o servidor de proxy reverso te manda o contedo da resposta do servidor de aplicao.

uma imagem descrevendo um request na internet, passando por nginx como proxy reverso e indo pra aplicao final

Vamos criar uma aplicao de teste que responde na porta 8081, mas que vamos acessar atravs do nosso NGINX.

A aplicao vai ser em Python usando Flask.

from flask import Flaskapp = Flask(__name__)@app.route("/")def index():    return "<p>Index page!</p>"

Modificamos nossa configurao do servidor para conter apenas a rota da aplicao. Agora com a adio da diretiva proxy_pass, que usada para fazer do NGINX um servidor de proxy reverso.

server {  listen 80;  location / {    proxy_pass http://app:8081;  }}

Observe que usamos o nome do servio descrito (app) no docker-compose para referenciar o nome que a aplicao atende.

curl -v http://localhost:8080< HTTP/1.1 200 OK< Server: nginx/1.21.6< Content-Type: text/html; charset=utf-8< Content-Length: 18< Connection: keep-alive<p>Index page!</p>

Podemos ver que a resposta possui um header adicional (Content-Type), agora, alm da resposta que veio da aplicao.

Como fazer proxy reverso pra mltiplos servidores?

A realidade de uma aplicao em produo, na grande maioria das vezes, ter mais de um servidor pra servir ela. E isso se deve a inmeros motivos. Servidores tm recursos finitos (placa de rede, disco, CPU) para atender muitas requisies. E no apenas sobre isso. E se o servidor sofrer uma falha de hardware? Ou at alguma falha de rede? Inmeros motivos podem fazer sua aplicao ficar sem um fallback pra esses casos.

a que entramos com a diretiva upstream do NGINX, usada para definir um conjunto de servidores usados para balancear sua aplicao.

Primeiramente, modificaremos nosso docker-compose para criar duas instncias da aplicao. Para fins de exemplo, no usaremos a diretiva scale porque ela possui um balanceamento round robin, e queremos mostrar como usar a diretiva de upstream com mltiplos servidores de aplicao.

app_1:  build: app  ports:    - "8081:8081"  environment:    - FLASK_RUN_PORT=8081    - FLASK_RUN_HOST=0.0.0.0app_2:  build: app  ports:    - "8082:8081"  environment:    - FLASK_RUN_PORT=8081    - FLASK_RUN_HOST=0.0.0.0

Vamos modificar nossa configurao para criar um upstream e colocar os dois hostnames da nossa aplicao:

upstream app {  server app_1:8081;  server app_2:8081;  keepalive 100;}server {  listen 80;  location / {    proxy_pass http://app;  }}

Definimos um upstream chamado app, e esse nome que usamos na diretiva proxy_pass. Usar proxy_pass tem algumas vantagens em vez de usar o proxy_pass diretamente com um IP ou hostname:

  • Definir diferentes estratgias de balanceamento dos servidores de aplicao (algoritmos de balanceamento diferente com pesos diferentes para cada servidor);
  • Usar keepalive, um nmero inteiro do total de conexes TCP mantidas do NGINX com o servidor, evitando criar conexes TCP a todo request;
  • Resoluo de DNS feita quando o servidor sobe. Sem definir um upstream, um nome como google.com no proxy_pass vai gerar uma consulta de DNS por request. Em larga escala isso pode ser um gargalo (at para o DNS interno da sua empresa, caso exista).

A configurao que fizemos vai balancear os request de forma igual, 50% pra cada servidor. Olhando nos logs, podemos ver isso acontecendo na prtica:

nginx-intro-nginx-1  | 192.168.144.1 - - [20/May/2022:16:33:48 +0000] "GET / HTTP/1.1" 200 18 "-" "curl/7.79.1"nginx-intro-app_1-1  | 192.168.144.4 - - [20/May/2022 16:33:48] "GET / HTTP/1.0" 200 -nginx-intro-nginx-1  | 192.168.144.1 - - [20/May/2022:16:33:50 +0000] "GET / HTTP/1.1" 200 18 "-" "curl/7.79.1"nginx-intro-app_2-1  | 192.168.144.4 - - [20/May/2022 16:33:50] "GET / HTTP/1.0" 200 -nginx-intro-nginx-1  | 192.168.144.1 - - [20/May/2022:16:33:53 +0000] "GET / HTTP/1.1" 200 18 "-" "curl/7.79.1"nginx-intro-app_1-1  | 192.168.144.4 - - [20/May/2022 16:33:53] "GET / HTTP/1.0" 200 -nginx-intro-nginx-1  | 192.168.144.1 - - [20/May/2022:16:33:55 +0000] "GET / HTTP/1.1" 200 18 "-" "curl/7.79.1"nginx-intro-app_2-1  | 192.168.144.4 - - [20/May/2022 16:33:55] "GET / HTTP/1.0" 200 -

Agora, vamos dar uma olhada em como funciona o sistema de cache do NGINX.

Utilizando o NGINX como um servidor de cache

Muita da informao que consumimos no precisa, necessariamente, estar 100% atualizada a todo o instante. Se temos um arquivo esttico como um script, uma foto ou um vdeo em nosso site, no precisamos ir buscar ou gerar esse contedo a todo momento. Podemos nos utilizar do NGINX como um servidor de cache em alguns passos, fazendo cache de diversos requests da sua aplicao.

Primeiro, vamos adicionar uma rota que trabalha com um parmetro de query:

@app.route("/hello")def hello():    name = request.args.get("name", "nobody")    return f"<p>Hello, {name}</p>"

Agora, vamos modificar o NGINX para ele fazer cache das respostas.

worker_processes auto;events {  worker_connections 1024;}http {  proxy_cache_path /tmp/cache levels=1:2 keys_zone=app_cache:5m max_size=10m inactive=20m use_temp_path=off;  upstream app {    server app_1:8081;    server app_2:8081;    keepalive 100;  }  server {    listen 80;    location / {      add_header X-Cache-Status $upstream_cache_status;      proxy_cache app_cache;      proxy_cache_valid 200 30s;      proxy_cache_valid 404 1m;      proxy_cache_key $host$uri$is_args$args;      proxy_cache_lock on;      proxy_pass http://app;    }  }}

O que significa cada diretiva de proxy adicionada?

  • proxy_cache_path - descreve onde vamos guardar o cache. Os arquivos de cache so guardados em arquivos.
  • add_header - adiciona um header X-Cache-Status na resposta para que possamos depurar quando aconteceu MISS, HIT, etc.
    • HIT - contedo veio diretamente do cache por estar vlido, ainda.
    • MISS - contedo no foi achado no cache e precisou ser buscado na origem.
  • proxy_cache - zona do cache. A mesma zona pode ser usada em outros lugares da configurao.
  • proxy_cache_valid - define um tempo de validade do cache para um cdigo HTTP especfico. Nossa aplicao no define um header Cache-Control, ento, configuramos ele direto no NGINX.
  • proxy_cache_key - parmetros usados para montar a chave de cache. Essa montagem de valores extremamente importante para construir um cache seguro e eficiente.
  • proxy_cache_lock - impede que mais de um request v na origem para buscar o mesmo contedo. Uma diretiva importante para proteger a origem do contedo. As conexes esperam at que o cache seja populado.

Conferindo o resultado, podemos fazer uma requisio pra rota nova:

curl -v "http://localhost:8080/hello?name=bento"
nginx-intro-nginx-1  | 192.168.176.1 - - [20/May/2022:22:04:51 +0000] "GET /hello?name=bento HTTP/1.1" 200 19 "-" "curl/7.79.1"nginx-intro-app_1-1  | 192.168.176.4 - - [20/May/2022 22:04:51] "GET /hello?name=bento HTTP/1.0" 200 -nginx-intro-nginx-1  | 192.168.176.1 - - [20/May/2022:22:04:55 +0000] "GET /hello?name=bento HTTP/1.1" 200 19 "-" "curl/7.79.1"nginx-intro-nginx-1  | 192.168.176.1 - - [20/May/2022:22:04:57 +0000] "GET /hello?name=bento HTTP/1.1" 200 19 "-" "curl/7.79.1"nginx-intro-nginx-1  | 192.168.176.1 - - [20/May/2022:22:04:58 +0000] "GET /hello?name=bento HTTP/1.1" 200 19 "-" "curl/7.79.1"nginx-intro-nginx-1  | 192.168.176.1 - - [20/May/2022:22:04:59 +0000] "GET /hello?name=bento HTTP/1.1" 200 19 "-" "curl/7.79.1"nginx-intro-nginx-1  | 192.168.176.1 - - [20/May/2022:22:06:05 +0000] "GET /hello?name=bento HTTP/1.1" 200 19 "-" "curl/7.79.1"nginx-intro-app_2-1  | 192.168.176.4 - - [20/May/2022 22:06:05] "GET /hello?name=bento HTTP/1.0" 200 -

Observe como o primeiro request bate no NGINX e na app. Os requests em sequncia no vo at a app porque eles esto usando o cache que orientamos o servidor a fazer.

Nos ltimos dois requests possvel ver que o request foi pra outra instncia da app porque passou os 30 segundos de validade que configuramos, garantindo que o cache precisa ser revalidado e que o balanceamento continua funcionando.

Prximos passos

Ao mesmo tempo que isso o bsico de NGINX , tambm, o suficiente para voc desbravar mais utilidades pra ele. possvel adicionar muita lgica de aplicao no NGINX que pode ajudar voc a construir aplicaes mais focadas na regra de negcio em vez de focar em balanceamento, cache, autorizao, etc.

NGINX possui suporte a embutir cdigo dinmicamente, sendo as principais Lua e Javascript.


Original Link: https://dev.to/mauricioabreu/uma-introducao-ao-nginx-1jdg

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To