O que fica na frente de quase todos os serviços web
Bem-vindo
Se você digitar example.com em um navegador, quase nunca chega ao dispositivo que realmente executa a aplicação. Você chega a um dispositivo que encaminha a solicitação para um que faz. Esse dispositivo de encaminhamento carrega um nome: um reverse proxy.
Esta aula ensina o que um reverse proxy faz, por que quase todos os serviços web públicos escondem atrás de um e o que três funções a camada de borda manipula ao mesmo tempo.
Ao final, você entenderá:
- A diferença entre um cliente, um proxy e um origin
- Por que um proxy na frente de um origin protege, escala e permite que você substitua peças sem que ninguém perceba
- As três funções que um reverse proxy manipula ao mesmo tempo: esconder o origin, encerrar TLS e distribuir carga entre réplicas
- Como uma solicitação viaja do navegador para o proxy para o upstream e de volta, pulando de um para outro
Ao final, você raciocinará com confiança sobre a localização do proxy, a separação de preocupações na borda e por que uma camada de proxy sem estado se multiplica enquanto um único origin não faz.
Forward Proxy vs Reverse Proxy
Dois sentidos de proxy
Ambos os tipos de proxy ficam entre duas partes e retransmitem tráfego. Eles se diferenciam em qual parte eles representam.
Forward proxy: fica na frente de um grupo de clientes. Os clientes sabem sobre um proxy; um servidor externo vê uma endereço de proxy, não um endereço de cliente.
Reverse proxy: fica na frente de um grupo de servidores. O mundo externo (clientes) fala com um endereço de proxy; os clientes não têm ideia de que um verdadeiro servidor está escondido por trás dele. Quase todos os serviços web públicos usam isso.
Mnemonico: um forward proxy esconde clientes de servidores. Um reverse proxy esconde servidores de clientes.
Por que se importar com qual direção? A função, os modos de falha e a barreira de segurança são diferentes. Um forward proxy se preocupa com quem seus usuários contatam; um reverse proxy se preocupa com quem contata seus servidores.
Um cliente enviando tráfego através de ambos os tipos de uma vez: cliente -> forward_proxy -> internet -> reverse_proxy -> origin.
Por Que Tanto se Encontra na Camada de Edge
A Camada de Edge Ganha Sua Hora
Um proxy reverso carrega três funções ao mesmo tempo. Qualquer uma delas justifica a camada; carregar todas três no mesmo endereço explica por que quase toda arquitetura de produção de web tem a mesma forma na parte da frente.
Função 1: Esconder o origem. O proxy responde em uma IP pública. Backends ficam em IPs privados que a internet não pode alcançar. Um atacante que deseja atingir a origem primeiro precisa comprometer o proxy.
Função 2: Encerrar TLS. O proxy possui o certificado para example.com e decifra as solicitações HTTPS vindas da internet. Backends falam HTTP sem encerramento (ou TLS mais simples) para o proxy em uma segmento de rede confiável. A rotação de certificados, renovação e política de cifra tudo fica em um lugar.
Função 3: Distribuir carga. O proxy escolhe qual backend lidará com cada solicitação. Backends por trás de um proxy formam uma piscina; o proxy escolhe um por solicitação usando uma estratégia (em rotação, menos conexões, hash em uma cabeçalho). Adicionar capacidade significa adicionar um backend à piscina, não informar a todos os clientes um novo endereço.
Cada função é um pequeno programa. Juntos, eles explicam por que uma camada tão simples quanto 'Caddy na frente de uma aplicação Python' carrega mais peso de design do que a própria aplicação Python.
Projeto para Todas Três
Seu time opera uma pequena API em um único processo Python ouvindo na porta 8000 em uma única VM. O tráfego cresceu o suficiente que uma única VM não consegue mais lidar e uma revisão de segurança identificou que a VM possui uma IP pública e possui seu próprio certificado TLS.
Você decide colocar um proxy reverso na frente. Desenhe a configuração: para onde o DNS aponta, onde o certificado vive, como a carga chega aos backends e o que muda sobre a VM original.
Troque uma Peça Sem Que Ninguém Note
Indireção Compra Liberdade
Um velho adágio da ciência da computação afirma: todo problema pode ser resolvido adicionando uma camada de indireção (exceto o problema de muitas camadas de indireção). A reversa proxy é uma das indireções mais úteis nos sistemas distribuídos.
O que você compra:
- Backends substituíveis. Mude a aplicação do Python para Go? Migrar de um datacenter para outro? Lançar uma nova versão com zero de downtime? Cada um acontece atrás de uma endereço público estável. Nada muda para os usuários.
- Escala independente. A camada proxy escala em banda e CPU na camada TLS. A camada backend escala na trabalho de aplicação. Cada um cresce em seu próprio eixo porque eles vivem em máquinas diferentes.
- Contenção de falhas. Uma má implantação no backend não tira o endereço público. A proxy fica up; você empurra uma correção ou rola pra trás; o mundo se conecta quando o backend recupera.
- Preocupações transversais em um lugar. Limitação de taxa, bloqueio geográfico, registro de solicitações, reescrita de cabeçalhos, cache, compressão de resposta: tudo vive na proxy. O código backend fica focado na aplicação.
Sem a proxy cada um desses problemas deve viver dentro do processo de aplicação. Com a proxy eles vivem em uma camada que um time possui.
O custo: outra camada para operar. Times maduros aceitam o custo porque a camada proxy em si roda sem estado e escala horizontalmente; substituir uma proxy por duas não requer nenhuma coordenação.
Um Deploy Azul/Verde Por meio da Proxy
Seu time executa a versão 1 da API em três VMs de backend (pool azul) atrás de uma proxy reversa. Você quer lançar a versão 2 com a capacidade de reverter em menos de trinta segundos se algo der errado.
Lançar três novas VMs de backend (pool verde) executando a versão 2, lado a lado com o pool azul, mas ainda não roteiam nenhuma tráfego para eles.
De Navegador para Backend e de Volta
Siga uma Solicitação HTTPS GET de Ponta a Ponta
Marque uma única solicitação HTTPS GET de https://api.example.com/users/42 através de um proxy reverso em frente a uma piscina de backends.
Hop 1: Resolução de DNS. O navegador pergunta a um resolvente para api.example.com. O resolvente retorna o IP público do proxy (digamos, 203.0.113.10). O navegador abre uma conexão TCP para 203.0.113.10:443.
Hop 2: Troca de TLS. O proxy apresenta seu certificado para api.example.com. O navegador valida o certificado, os dois lados concordam com uma chave de sessão e o canal criptografado é aberto.
Hop 3: Solicitação HTTP dentro de TLS. O navegador envia GET /users/42 HTTP/1.1\nHost: api.example.com\n.... O proxy descriptografa os bytes da solicitação.
Hop 4: Seleção de backend. O proxy consulta sua piscina de backends para api.example.com e escolhe um backend (digamos 10.0.0.21:8000) usando sua estratégia de balanceamento de carga.
Hop 5: Solicitação upstream. O proxy abre (ou reusa) uma conexão HTTP simples para 10.0.0.21:8000 e encaminha a solicitação. O proxy pode reescrever cabeçalhos ao longo do caminho: adicionar X-Forwarded-For: <client-ip>, definir corretamente Host:, remover cabeçalhos como Connection que são hop-by-hop.
Hop 6: Processamento upstream. A aplicação backend lê a solicitação, consulta seu banco de dados e constrói uma resposta em JSON.
Hop 7: Resposta upstream. O backend envia a resposta de volta para o proxy como HTTP simples.
Hop 8: Resposta de borda. O proxy pode reescrever ou compactar a resposta, criptografá-la novamente através da sessão TLS e enviar para o navegador.
Hop 9: Ciclo de vida da conexão. A sessão TLS geralmente fica aberta para a próxima solicitação (HTTP/2 multiplexa várias solicitações em uma conexão). A conexão proxy-to-backend geralmente poola para reuso.
Cada serviço web público segue uma variante desta forma. Saber os hops permite que você raciocine sobre onde a latência se acumula, onde o logging pertence e onde um erro pode estar escondido.
Onde o Tempo Sumiu?
Um usuário reclama que a API parece lenta. Você mede e encontra que a solicitação leva 850 ms do início ao fim. Os logs do servidor no backend mostram que a aplicação atendeu à solicitação em 40 ms. Os logs do proxy mostram que o proxy gastou 50 ms no seu lado do trabalho (TLS, roteamento e escrita da resposta).
Projete uma Arquitetura Mínima de Edge para um Novo Serviço
Síntese
Você aprendeu a diferença entre um forward e reverse proxy, as três tarefas que um reverse proxy realiza ao mesmo tempo, por que esconder o origin paga dividendos a cada vez que você precisa mudar algo, e como uma solicitação flui de hop em hop através da edge.
Agora aplique isso.
Um pequeno time planeja lançar um novo serviço chamado notes.example.com. Os usuários lerão e escreverão notas pessoais. O time executará duas VMs de backend no lançamento e espera escalar para dez no próximo ano. Eles querem HTTPS para os usuários, lançamento gradual para novas versões e nenhuma exposição pública de IPs de backend.
Para onde este curso vai em seguida
Para onde este curso vai em seguida
Esta lição estabeleceu a forma da camada de edge. Quatro lições adicionais neste curso se baseiam nisso:
- Escala Horizontal Sem Estado: por que uma camada de proxy (& os backends por trás dele) se multiplica baratamente, & a matemática para dimensionar contagens de réplicas sob surto.
- Separação de Ingresso / Egresso: por que uma caixa de proxy única que manipula tráfego de entrada & saída eventualmente falha de maneiras surpreendentes, & como dividir as camadas.
- Modos de Falha & Raio de Explosão: como uma alteração de configuração se espalha em uma interrupção, & como escrever itens de ação sem culpa que evitem a repetição.
- Observabilidade & Capacidade: o que medir na borda para descobrir que algo está quebrado antes que os usuários percebam.
Cada lição é autônoma. Juntas, elas lhe dão um modelo mental de trabalho de uma frota de web-escala.
Aula complementar: geometry_of_proxies_and_origins reformula tudo nesta lição como um grafo direcionado & explora o que a teoria dos grafos diz sobre um caminho de solicitação.
Bem feito. Em frente.