Por Que devo usar um Proxy inverso se nó.o js está pronto para a produção?
era O ano de 2012. PHP e Ruby on Rails reinaram como as tecnologias do lado do servidor supremo para renderização de aplicações web. Mas, um novo candidato ousado tomou a comunidade de assalto-um que conseguiu lidar com 1m conexões simultâneas. Esta tecnologia não era nada mais do que um nó.js e tem aumentado constantemente em popularidade desde então.
Ao contrário da maioria das tecnologias concorrentes do tempo, nó.o js veio com um servidor Web incorporado. Ter este servidor significava que os desenvolvedores poderiam contornar uma miríade de arquivos de configuração, como php.ini
e uma coleção hierárquica de.htaccess
arquivos. Ter um servidor Web incorporado também oferecia outras conveniências, como a capacidade de processar arquivos como eles estavam sendo carregados e a facilidade de implementar WebSockets.
nó diário.as aplicações web alimentadas pela js lidam com milhares de milhões de Pedidos. A maioria das maiores empresas do mundo são alimentadas de alguma forma pelo Nodo.js. Para dizer esse nó.js is Production-Ready is certainly an
understatement. No entanto, há um conselho que se mantém verdadeiro desde o nodo.concepção de js: não se deve expor diretamente um nó.js processo para a web e deve, em vez disso, escondê-lo atrás de um proxy reverso. Mas, antes de olharmos para as razões pelas quais queremos usar um proxy reverso, vamos primeiro olhar para o que um é.
um proxy reverso é basicamente um tipo especial de servidor web que recebe pedidos, encaminha-os para outro Servidor HTTP em algum outro lugar, recebe uma resposta, e encaminha a resposta para o solicitador original.
um proxy reverso geralmente não envia o pedido exato, no entanto. Normalmente irá modificar o pedido de alguma forma. Por exemplo, se o proxy reverso vidas em: www.example.org:80
, e vai encaminhar o pedido paraex.example.org:8080
, ele provavelmente irá reescrever o original Host
cabeçalho de partida que do alvo. Ele também pode modificar o pedido de outras formas, tais como limpar uma solicitação malformada ou traduzir entre protocolos.
Uma vez que o proxy reverso recebe uma resposta, ele pode então traduzir essa resposta de alguma forma. Mais uma vez, uma abordagem comum é modificar o cabeçalho Host
para corresponder ao pedido original. O corpo dos pedidos também pode ser alterado. Uma modificação comum é realizar compressão gzip na resposta. Outra mudança comum é permitir o Suporte de HTTPS quando o serviço subjacente só fala HTTP.
proxies invertidos também podem enviar pedidos recebidos para várias instâncias de infra-estrutura. Se um serviço é exposto no api.example.org
, um proxy reverso pode reencaminhar pedidos para api1.internal.example.org
api2
, etc.
existem muitos proxies reversos diferentes lá fora. Dois dos mais populares são Nginx e HAProxy. Ambas as ferramentas são capazes de executar compressão gzip e adicionar suporte HTTPS, e eles se especializam em outras áreas também. Nginx é o mais popular das duas escolhas, e também tem algumas outras capacidades benéficas
como a capacidade de servir arquivos estáticos de um sistema de arquivos, então vamos usá-lo como um exemplo ao longo deste artigo.
Agora que sabemos o que é um proxy reverso, podemos agora olhar para o porquê de querermos fazer uso de um com nó.js.por que devo usar um Proxy inverso?
a terminação SSL é uma das razões mais populares que se usa um proxy reverso. Mudar a aplicação do protocolo de ones de http
para https
requer um pouco mais de trabalho do que adicionar um s
. No.js em si é capaz de executar a criptografia necessária e decriptação para https
, e pode ser configurado para ler os arquivos de certificado necessários.
no entanto, configurar o protocolo usado para comunicar com a nossa aplicação, e gerir certificados SSL sempre expirados, não é realmente algo que a nossa aplicação precisa de se preocupar. Verificar certificados em uma base de código não seria apenas tedioso, mas também um risco de segurança. A aquisição de certificados a partir de uma localização central após a inicialização da aplicação também tem os seus riscos.
Por esta razão é melhor executar a terminação SSL fora da aplicação, geralmente dentro de um proxy reverso. Graças a tecnologias como certbot
by Let’s Encrypt, a manutenção de certificados com Nginx é tão fácil quanto a criação de um trabalho cron. Tal trabalho pode instalar automaticamente novos certificados e reconfigurar dinamicamente o processo Nginx. Este é um processo muito menos disruptivo, então, digamos, reiniciando cada nó.instância de Aplicação js.
também, ao permitir que um proxy reverso execute a terminação SSL, isto significa que apenas o código escrito pelos autores do proxy reverso tem acesso ao seu certificado SSL privado. No entanto, se o teu nó.a aplicação js está lidando com SSL, então cada módulo de terceiros usado pela sua aplicação — mesmo módulos potencialmente maliciosos — terá acesso ao seu certificado SSL privado.
compressão gzip
compressão gzip é outra característica que você deve descarregar da aplicação para um proxy reverso. as Políticas de compressão gzip são algo melhor definido em um nível de organização, em vez de ter que especificar e configurar para cada aplicação.
é melhor usar alguma lógica ao decidir o que fazer com gzip. Por exemplo, arquivos que são muito pequenos, talvez menores que 1kb, provavelmente não valem a pena comprimir como a versão comprimida gzip pode às vezes ser maior, ou a sobrecarga de CPU de ter o cliente descomprimir o arquivo pode não valer a pena. Além disso, ao lidar com dados binários, dependendo do formato ele pode não se beneficiar da compressão. o gzip também é algo que não pode ser simplesmente ativado ou desativado, ele requer examinar o cabeçalho Accept-Encoding
para algoritmos de compressão compatíveis.
Clustering
JavaScript is a single-threaded language, and according, Node.js tem sido tradicionalmente uma plataforma de servidor simples (embora, o Suporte de thread de trabalho experimental atualmente disponível no Node.js v10 visa mudar isso). Isto significa obter o máximo de transferência de um nó.a aplicação js o quanto possível requer executar aproximadamente o mesmo número de instâncias que existem núcleos de CPU.
nó.js vem com um módulo embutido cluster
que pode fazer exatamente isso. Pedidos HTTP de entrada serão feitos para um processo mestre, em seguida, ser enviado para os trabalhadores de cluster.
no entanto, dinamicamente escalando trabalhadores de clusters levaria algum esforço. Há também geralmente adicionado overhead na execução de um nó adicional.processo js como o processo mestre de envio. Além disso, a escala de processos em diferentes máquinas é algo que cluster
não pode fazer.
Por estas razões, às vezes é melhor usar um proxy reverso para enviar pedidos para o nó em execução.processos js. Tais proxies inversos podem ser configurados dinamicamente para apontar para novos processos de aplicação à medida que chegam. Realmente, uma aplicação deve apenas se preocupar com fazer o seu próprio trabalho, não deve se preocupar com a gestão de múltiplas cópias e envio de Pedidos.
roteamento da empresa
ao lidar com aplicações web maciças, tais como as construídas por empresas multi-equipe, é muito útil ter um proxy reverso para determinar para onde enviar pedidos. Por exemplo, os pedidos feitos a example.org/search/*
podem ser encaminhados para o aplicativo de pesquisa interna, enquanto outros pedidos feitos a example.org/profile/*
podem ser enviados para o aplicativo de perfil interno.
tal ferramenta permite outras características poderosas, tais como sessões pegajosas, desdobramentos Azul/Verde, testes A/B, etc. Eu trabalhei pessoalmente em uma base de código onde tal Lógica foi realizada dentro da aplicação e esta abordagem fez a aplicação muito difícil de manter.
benefícios de desempenho
nó.o js é altamente maleável. Ele é capaz de servir ativos estáticos de um sistema de arquivos, executar compressão gzip com respostas HTTP, vem com suporte embutido para HTTPS, e muitos outros recursos. Ele ainda tem a capacidade de executar várias instâncias de uma aplicação e executar seu próprio pedido de envio, por meio do módulo cluster
.
E, no entanto, em última análise, é do nosso interesse deixar um proxy reverso lidar com estas operações para nós, em vez de ter o nosso nó.a aplicação js fá-lo. Além de cada uma das razões listadas acima, outra razão para querer fazer essas operações fora do nó.js é devido à eficiência.
encriptação SSL e compressão gzip são duas operações altamente ligadas ao CPU. Ferramentas de proxy inversas dedicadas, como Nginx e HAProxy, normalmente executam essas operações mais rápido do que o nó.js. Ter um servidor web como Nginx ler conteúdo estático do disco vai ser mais rápido do que o nó.js também. Mesmo a clustering pode às vezes ser mais eficiente como um proxy reverso como Nginx irá usar menos memória e CPU do que o de um nó adicional.processo js.mas não acredite na nossa palavra. Vamos fazer alguns testes!
a seguinte carga testada foi realizada usando siege
. Executamos o comando com um valor de concorrência de 10 (10 usuários simultâneos fazendo um pedido) e o comando seria executado até 20.000 iterações foram feitas (para 200.000 pedidos globais).
para verificar a memória, executamos o comandopmap <pid> | grep total
algumas vezes ao longo da vida do benchmark, em seguida, a média dos resultados. Ao executar Nginx com um único fio de trabalho lá acabam sendo duas instâncias correndo, uma sendo o mestre e a outra sendo o trabalhador. Então somamos os dois valores. Ao executar um nó.js cluster of 2 there will be 3 processes, one being the master and the other two being workers. A coluna de memória approx na tabela seguinte é uma soma total de cada Nginx e nó.processo js para o teste em questão.
Aqui estão os resultados do benchmark:
node-cluster
benchmark usamos 2 trabalhadores. Isto significa que há 3 nódulos.processos js em execução: 1 mestre e 2 trabalhadores. In the nginx-cluster-node
benchmark we have 2 Node.processos js em execução. Cada teste da Nginx tem um único mestre da Nginx e um único processo de trabalhador da Nginx. Benchmarks envolvem a leitura de um arquivo de disco, e nem Nginx nem Nodo.js foram configurados para cache o arquivo em memória.
Usando Nginx para executar a terminação de SSL para o nó.a js resulta num aumento do rendimento de ~16% (749 RPS para 865 RPS). A utilização da Nginx para realizar a compressão gzip resulta num aumento do rendimento de ~50% (5.047 rps para 7.590 rps). Usando o Nginx para gerenciar um cluster de processos resultou em uma penalidade de desempenho de ~-1% (8,006 rps para 7,908 rps), provavelmente devido à sobrecarga de passar um pedido adicional sobre o dispositivo de rede loopback.
essencialmente o uso da memória de um único nó.js process is ~600MB, while the memory usage of an Nginx process is around ~50MB. Estes podem flutuar um pouco dependendo das características que estão sendo usadas, por exemplo, nó.js usa um ~13MB adicional ao executar a terminação SSL, e Nginx usa um ~4MB adicional quando usado como um verso proxy reverso servindo conteúdo estático do sistema de arquivos. Uma coisa interessante a notar é que Nginx usa uma quantidade consistente de memória ao longo de sua vida. No Entanto, Nó.js flutua constantemente devido à natureza de coleta de lixo do JavaScript.
qui estão as versões do software utilizado ao executar este parâmetro de referência:
- Nginx:
1.14.2
- Node.js:
10.15.3
- Siege:
3.0.8
Os testes foram realizados em uma máquina com 16GB de memória, de uma i7-7500U CPU 4x2.70GHz
e Linux kernel 4.19.10
. Todos os arquivos necessários para recriar os benchmarks acima estão disponíveis aqui:
IntrinsicLabs / nodejs-reverse-proxy-benchmarks.
código de Aplicação simplificado
Benchmarks são bons e tudo, mas na minha opinião os maiores benefícios do trabalho de offloading de um nó.a aplicação js para um proxy reverso é a de simplicidade de código. Podemos reduzir o número de linhas de código de aplicação potencialmente buggy imperativo e trocá-lo por configuração declarativa. Um sentimento comum entre os desenvolvedores é que eles estão mais confiantes em código escrito por uma equipe externa de engenheiros — como Nginx — do que em código escrito por eles mesmos.
em vez de instalar e gerir o middleware de compressão gzip e mantê-lo actualizado através de vários nós.projetos js podemos configurá-lo em um único local. Em vez de enviar ou baixar certificados SSL e ou re-adquiri-los ou reiniciar processos de aplicação, podemos, em vez disso, usar ferramentas de gerenciamento de certificados existentes. Em vez de adicionar condicionalismos à nossa aplicação para verificar se um processo é um mestre ou trabalhador, podemos descarregar isto para outra ferramenta.
um proxy reverso permite que a nossa aplicação se concentre na lógica de negócios e esqueça os protocolos e a gestão de processos.