Qual é a diferença entre OpenResty e NGINX?

API7.ai

September 9, 2022

OpenResty (NGINX + Lua)

As vantagens do OpenResty são evidentes. Antes de aprendermos em detalhes, vamos revisar brevemente o processo de desenvolvimento do OpenResty, o que ajudará você a entender melhor o conteúdo a seguir.

Processo de desenvolvimento do OpenResty

O OpenResty não foi construído do zero como outras linguagens de desenvolvimento, mas é baseado em componentes de código aberto maduros - NGINX e LuaJIT. O OpenResty nasceu em 2007, mas sua primeira versão não escolheu Lua, e sim Perl, o que tem muito a ver com a preferência técnica do autor.

No entanto, o desempenho do Perl estava longe de atender aos requisitos, então, na segunda versão, Perl foi substituído por Lua. Ainda assim, no projeto oficial do OpenResty, Perl ainda desempenha um papel importante. Projetos do ecossistema OpenResty são construídos com Perl, como frameworks de teste, Linter, CLI, etc. Vamos apresentá-los passo a passo mais tarde.

Como o alto desempenho e as vantagens dinâmicas do OpenResty são muito adequados para as necessidades do negócio de CDN, o OpenResty logo se tornou o padrão técnico de CDN. Além disso, através das ricas bibliotecas lua-resty-*, o OpenResty começou a se libertar gradualmente da sombra do NGINX e formou seu próprio ecossistema, que é amplamente utilizado em gateway de API, soft WAF e outros campos.

Eu costumo dizer que o OpenResty é uma tecnologia amplamente utilizada, mas não é uma tecnologia quente, o que parece contraditório. O que isso significa?

É amplamente utilizado porque o OpenResty é agora o quinto servidor web mais extenso do mundo.

Não é popular porque a proporção de uso do OpenResty para construir sistemas de negócios não é alta. A maioria dos usuários usa o OpenResty para processar tráfego de entrada e não se aprofunda no negócio. Então, naturalmente, o uso do OpenResty é apenas superficial e suficiente para atender às necessidades atuais. Isso, é claro, também está relacionado à falta de frameworks web maduros e ecossistemas como Java e Python no OpenResty.

Dito isso, a seguir, vou me concentrar em apresentar alguns pontos onde o OpenResty, como projeto de código aberto, merece elogios e aprendizado.

Destaques do OpenResty

Documentação detalhada e casos de teste

Sim, documentação e testes são indicadores críticos de se um projeto de código aberto é confiável, até mesmo à frente da qualidade do código e do desempenho.

A documentação do OpenResty é muito detalhada, e o autor escreveu cada ponto que precisa de atenção na documentação. Na maioria das vezes, só precisamos olhar cuidadosamente a documentação para resolver o problema que encontramos, sem precisar pesquisar no Google ou rastrear o código-fonte. Para conveniência, o OpenResty também vem com uma ferramenta de linha de comando, restydoc, projetada para ajudá-lo a visualizar a documentação através do shell e evitar interrupções no processo de codificação.

No entanto, há apenas um ou dois trechos de código disponíveis na documentação, e não há exemplos completos e complexos. Onde posso encontrar esses exemplos?

Para o OpenResty, naturalmente, é o diretório /t, que contém todos os casos de teste. Cada caso de teste inclui a configuração completa do NGINX e o código Lua, bem como os dados de entrada e saída esperados. No entanto, o framework de teste do OpenResty é completamente diferente de outros frameworks de teste de estilo de asserção, que apresentarei mais tarde em um capítulo específico.

Síncrono não bloqueante

Corrotina é um novo recurso que muitas linguagens de script adicionaram nos últimos anos para melhorar o desempenho. Mas elas não são perfeitamente implementadas, algumas são açúcar sintático, e outras exigem declarações explícitas de palavras-chave.

O OpenResty suporta corrotinas desde o início e implementa um modelo de programação síncrono não bloqueante. Isso é importante porque programadores também são humanos, e o código deve estar mais alinhado com os hábitos de pensamento humano. Callbacks explícitos e palavras-chave assíncronas interrompem o pensamento e dificultam a depuração.

Então, o que é síncrono não bloqueante? Vamos falar sobre síncrono primeiro. Isso é muito simples: executar sequencialmente de acordo com o código. Por exemplo, o seguinte pseudocódigo:

local res, err  = query-mysql(sql)
local value, err = query-redis(key)

Na mesma requisição, se tivermos que esperar o resultado da consulta do MySQL retornar antes de continuar a consultar o Redis, isso é síncrono; se não precisarmos esperar o retorno do MySQL e pudermos continuar a consultar o Redis, então é assíncrono. Para o OpenResty, a maioria das operações são síncronas. Apenas APIs relacionadas a temporizadores em segundo plano, como ngx.timer, são operações assíncronas.

Quanto ao não bloqueante, que é um conceito facilmente confundido com assíncrono, quando dizemos bloqueante aqui, estamos nos referindo ao bloqueio da thread do sistema operacional. Vamos continuar olhando o exemplo acima, assumindo que leva 1s para consultar o MySQL. Se dentro desse 1s, os recursos do sistema operacional (CPU) estiverem ociosos e esperando o retorno, isso é bloqueante; se a CPU aproveitar a oportunidade para processar outras requisições de conexão, isso é não bloqueante. Não bloqueante também é a chave para realizar altas concorrências como C10K e C100K.

O conceito de síncrono não bloqueante é essencial. No entanto, na minha opinião, esse conceito não deve ser entendido por analogia, porque a analogia inadequada provavelmente o confundirá ainda mais.

No OpenResty, o pseudocódigo acima pode alcançar diretamente o síncrono não bloqueante sem palavras-chave explícitas. Isso reflete novamente que facilitar o uso para os desenvolvedores é um dos conceitos do OpenResty.

Dinamismo

Uma enorme vantagem do OpenResty, que não foi totalmente explorada, é seu dinamismo.

Servidores web tradicionais, como o NGINX, exigem que modifiquemos o arquivo de configuração no disco e o recarreguemos para que as alterações entrem em vigor, pois eles não fornecem APIs para controlar o comportamento em tempo de execução. Portanto, em microsserviços que exigem alterações frequentes, o NGINX tentou muitas vezes, mas nada foi melhorado. E o surgimento repentino do Envoy, com a API de controle dinâmico xDS, representa uma grande ameaça de ataque de redução de dimensionalidade ao NGINX.

Diferente do NGINX e do Envoy, o OpenResty é controlado pela linguagem de script Lua, e o dinamismo é uma vantagem natural da Lua. Por exemplo, através da API Lua fornecida no módulo lua-nginx-module no OpenResty, podemos controlar dinamicamente rotas, upstreams, certificados SSL, requisições, respostas, etc. Indo ainda mais longe, podemos modificar a lógica de processamento do negócio sem reiniciar o OpenResty, não limitado à API Lua fornecida pelo OpenResty.

Aqui está uma excelente analogia para ajudá-lo a entender o que foi dito sobre dinamismo acima. Pense em um servidor web como um carro que está acelerando na estrada, o NGINX precisa parar para trocar os pneus e mudar a cor da pintura; o Envoy pode trocar os pneus e as cores enquanto está em movimento; e o OpenResty, além das capacidades anteriores, também pode se transformar em um SUV sem precisar parar.

Após dominar essa habilidade mágica, o círculo de competência e imaginação do OpenResty se expandiu para outros campos, como Serverless e Edge computing.

O que deve ser aprendido?

Depois de falar sobre tantas características críticas do OpenResty, o que devemos aprender? Eu prefiro focar na linha principal em vez de tentar abraçar tudo, para que possamos construir um sistema de conhecimento com um contexto claro.

Você deve saber que, por mais abrangente que seja um curso, é impossível cobrir todos os problemas e não pode ajudá-lo diretamente a resolver todos os bugs e exceções online.

Voltando ao estudo do OpenResty, na minha opinião, se você quiser aprender bem o OpenResty, deve entender os seguintes oito pontos-chave:

  • Modelo de programação síncrono não bloqueante
  • Papel das diferentes fases de Requisição/Resposta
  • Diferenças entre LuaJIT e Lua
  • API do OpenResty e bibliotecas circundantes
  • Corrotina e cosocket
  • Framework de teste unitário e ferramentas de teste de desempenho
  • Gráfico de chama e cadeia de ferramentas circundante
  • Otimização de desempenho

Esses pontos são essenciais em nosso estudo, e vou discutir cada um deles separadamente em cada capítulo. No entanto, no processo de aprendizagem, espero que você possa tirar inferências de um caso e ler alguns capítulos em profundidade de acordo com seus interesses e background.

Se você é um iniciante no OpenResty, pode seguir o progresso do curso, instalar o OpenResty em seu ambiente e executar e modificar o código de exemplo. Lembre-se, seu foco está em construir o panorama geral do OpenResty, não em se prender a um único ponto de conhecimento. Claro, se você tiver alguma dúvida, sinta-se à vontade para entrar em contato conosco no chat ao vivo.

Se você está usando o OpenResty em seu projeto, isso é ótimo! No entanto, acredito que quando você ler os capítulos sobre LuaJIT e otimização de desempenho, terá mais ressonância e aplicações práticas e verá a melhoria de desempenho antes e depois da otimização em seu projeto.

Além disso, se você quiser contribuir com código para o OpenResty e bibliotecas circundantes, o maior obstáculo não é entender os princípios do OpenResty ou como escrever módulos C do NGINX, mas sim casos de teste e especificações de código. Já vi muitos contribuidores do OpenResty (eu incluso) modificando repetidamente casos de teste e estilos de código em um PR, e há muitas regras não escritas. Portanto, as seções de especificação de código e teste unitário do curso são para você.

E se você é um engenheiro de QA, mesmo que não use o OpenResty, o framework de teste e o conjunto de ferramentas de análise de desempenho do OpenResty lhe darão muita inspiração. Afinal, o investimento e a acumulação do OpenResty em testes são bastante profundos.

Leitura adicional