Variáveis ​​Nginx com njs: simples, indolor e via JavaScript

njs é um intérprete JavaScript em um servidor da web leve com o qual você pode criar novas variáveis ​​nginx e solicitar manipuladores de estágio. Para que serve o njs? O que não pode? E por que eles fizeram isso? Essas e outras perguntas serão respondidas por Dmitry Volyntsev ( xeioex ), o desenvolvedor do nginx e o principal desenvolvedor do intérprete do njs.



- Dmitry, por que você precisava de scripts nas configurações do nginx?


- A primeira razão é a diretiva if . As pessoas que a viram pela primeira vez pensam que podem ser usadas imperativamente. Na verdade, não é assim - a configuração do nginx é declarativa. No exemplo abaixo, você pode pensar que a resposta terá dois cabeçalhos: X-First e X-Second. Mas apenas o segundo cabeçalho receberá a resposta, porque o nginx é assim: se escrevermos duas diretivas se, então a última será selecionada.

 location /only-one-if { set $true 1; if ($true) { add_header X-First 1; } if ($true) { add_header X-Second 2; } 

A segunda razão é a que o nginx chegou agora. Anteriormente, era usado para armazenar em cache estatísticas e solicitações, além de balanceamento de carga - um conjunto de proxy clássico. A proliferação de microsserviços corroeu o escopo do nginx. Se as configurações anteriores terminassem com um par de localizações em vários back-ends em alguns idiomas, então, com a arquitetura de microsserviço, teríamos mais partes móveis. O back-end se tornou um monte de pequenos componentes. A lógica de autorização, por exemplo, precisa ser duplicada em cada microsserviço ou retirada, por exemplo, no frontend. Para implementar a autorização avançada, nem sempre existem mecanismos de solução internos suficientes no nginx.

Em terceiro lugar, no nginx, muitas diretivas aceitam expressões calculadas dinamicamente, por exemplo:

 proxy cache bypass $cookie_nocache $arg_nocache; 

Você pode concatenar variáveis ​​entre si ou com cadeias literais. Mas isso não é suficiente, e eu gostaria de ter ferramentas mais poderosas, por exemplo, para calcular o hash, trabalhar com dados numéricos, converter em maiúsculas e minúsculas.

Para expandir todos os gargalos no nginx, você precisa desenvolver sua própria sintaxe ou usar algo pronto. Chegamos à conclusão de que é melhor usar uma linguagem de programação de script existente. Portanto, os desenvolvedores não precisam aprender um novo idioma, o que também economizará tempo e diminuirá o limite de entrada. Escolhemos o JavaScript.

- E por que JavaScript?


- Escolhemos o JavaScript por vários motivos:

  • Um dialeto moderno, ideal para desenvolvedores que mudam de outros idiomas.
  • Estilo C. Isso é importante porque a configuração do nginx usa chaves, e no futuro queremos adicionar a capacidade de escrever código JS dentro da configuração. O aparelho nos ajudará com isso. Em Lua, por exemplo, o papel dos chavetas é desempenhado pelo começo e pelo fim - isso é inconveniente.
  • O modelo JavaScript se encaixa bem na arquitetura nginx.

"Então Lua também foi considerada?" É por causa do começo e do fim?


- Já existe um projeto de terceiros já pronto, o OpenResty. Se você não entrar em detalhes, isso é essencialmente nginx + Lua, mas ele possui uma arquitetura que é contrária ao nginx. Queríamos evitar interseções com esse ecossistema. Além disso, existem vários outros motivos:

  • Lua possui sintaxe semelhante a pascal.
  • As matrizes são indexadas a partir de 1.
  • Lua ainda é uma linguagem de programação de nicho.

- Como os njs se comparam aos concorrentes?


- Avaliamos os njs em comparação com os conhecidos motores - V8 e SpiderMonkey. Eles são ineficazes para tarefas dentro do nginx, porque são aprimorados por navegadores e muito pesados, e o nginx requer alta velocidade. Além disso, esses dois mecanismos estão evoluindo rapidamente, sua API é instável. Por fim, os njs podem ser mais eficientemente integrados ao nginx:


O número de contextos criados por segundo

- Quais padrões os njs suportam?


- No momento, quase todos os elementos básicos da especificação do ECMAScript 5.1 são implementados com alguma intercalação dos elementos das especificações 6 e 7. Ou seja, objetos padrão como Objeto, Matriz, String, Número, Data, RegExp, JSON. Encerramentos, funções anônimas e trabalhos com exceções são totalmente suportados.

Não estabelecemos como objetivo principal a total conformidade com as especificações de idioma. Portanto, no momento não há suporte para eval () e, até o momento, não pretendemos adicioná-lo. Mas planejamos adicionar suporte à const e deixar palavras-chave, bem como funções de seta.


O que é capaz e o que não é capaz de njs no momento

É importante mencionar mais uma coisa: a falta de coleta de lixo. A maioria das linguagens modernas monitora independentemente a vida útil dos objetos. Se o objeto não for mais usado, ele será excluído automaticamente. Você não pode prescindir desse mecanismo, mas geralmente precisa sacrificar algo por isso - o trabalho do programa diminui ou até para. Em njs, a memória não é liberada até que o objeto de solicitação seja liberado.

Essa abordagem tem seus prós e contras. A principal desvantagem é que ela não permite que você trabalhe efetivamente com consultas longas. Portanto, no futuro, planejamos adicionar a coleta de lixo como uma opção para habilitá-la conforme necessário.

- O que é njs não?


- Antes de responder a essa pergunta, gostaria de repetir mais uma vez que a principal tarefa do njs é expandir os recursos para configuração flexível do nginx e resolver tarefas no lado do proxy.

Agora a pergunta em si. O que deve ser considerado com antecedência?
  • njs não substitui o Node.js.
  • O pacote configurável nginx + njs não é um servidor de aplicativos.
  • O njs não implementa totalmente os padrões do ECMAScript, pois não há suporte para eval ().



Se este tópico for extremamente relevante para você e você desejar mais detalhes, recomendamos que assista à gravação em vídeo do relatório de Dmitry Volintsev no HighLoad ++ Siberia 2018, onde ele foi revelado por todos os lados.


Também convidamos todos os profissionais a enviarem seus relatórios para a conferência HighLoad ++ 2018 de novembro de 2018 , que será realizada em Skolkovo, nos dias 8 e 9 de novembro. Se você tem uma experiência única e interessante e está pronto para compartilhá-la, registre-se antes de 1º de setembro e preencha o formulário .

Se você tem medo de falar publicamente, temos a chamada escola de oradores , onde ajudamos a desenvolver essas habilidades gratuitamente.

Source: https://habr.com/ru/post/pt420465/


All Articles