E se houver um conflito entre as regras do Lua e a configuração do NGINX?
API7.ai
October 13, 2022
1. O nome e a linguagem do OpenResty
P: Até agora não entendi a origem do nome OpenResty. Além disso, o OpenResty decola com a linguagem Lua, então por que não com outras linguagens de script? Por exemplo, Shell, etc.
R: O OpenResty começou como um projeto corporativo da Yahoo!, que começou em outubro de 2007. O nome "Open" foi tirado de OpenAPI, e "Resty" foi tirado de rest API. Inicialmente, o OpenResty não foi concebido para ser um servidor web e plataforma de desenvolvimento, mas sim uma aplicação como um site.
Quando o OpenResty foi open-source há mais de uma década, muito poucas linguagens suportavam sincronização não bloqueante. Mesmo agora, não muitas linguagens de back-end podem alcançar esse nível de desempenho com o OpenResty. Atualmente, mais desenvolvedores estão usando o OpenResty em gateways de API e soft WAFs, o que é uma escolha natural para os desenvolvedores.
Quanto à linguagem, o OpenResty não é o único projeto que incorpora outras linguagens de desenvolvimento no NGINX. Por exemplo, o NGINX oficialmente incorpora JS; também há projetos open source que incorporam PHP no NGINX.
Normalmente, a escolha da linguagem a ser aproveitada é baseada em fatores como concorrência, JIT e popularidade da linguagem. Para o OpenResty, em 2007, Lua era de fato a melhor escolha. O OpenResty deu uma volta ao escolher perl em vez de Lua em suas versões mais antigas.
2. A prioridade das regras de configuração
P: Quando as regras Lua no OpenResty entram em conflito com o arquivo de configuração do NGINX, por exemplo, o NGINX configurou regras de rewrite, e ao mesmo tempo referencia rewrite_by_lua_file, qual é a prioridade dessas duas regras?
R: Na verdade, depende de como a regra de rewrite do NGINX é escrita, se é um break
ou last
, o que é declarado na documentação oficial do OpenResty, com um código de exemplo:
location /foo {
rewrite ^ /bar;
rewrite_by_lua 'ngx.exit(503)';
}
location /bar {
...
}
Nesta configuração do código de exemplo, ngx.exit(503)
não será executado.
No entanto, se você escrever assim, ngx.exit(503)
será executado.
rewrite ^ /bar break.
No entanto, recomendo usar o OpenResty para rewrite em vez da configuração do NGINX. Para evitar essa ambiguidade, muita configuração do NGINX é relativamente obscura e exige que você consulte a documentação para entendê-la repetidamente.
3. Por que meu código dá erro?
P: Na função de tabela da extensão LuaJIT, por que as duas linhas de código a seguir dão erro "moudule not found" quando executadas pelo LuaJIT? Estou usando a versão 2.0.5 do LuaJIT.
local new_tab = require('table.new')
# ou
require('table.clear')
# A execução vai reportar erro
luajit: table_luajit.lua:1: module 'table.new' not found:
R: Essas duas linhas de código exigem a versão 2.1 do LuaJIT para rodar, documentado aqui: https://github.com/LuaJIT/LuaJIT/blob/v2.1/doc/extensions.html#L218, Você pode descobrir sobre isso.
Como mencionamos, você precisa prestar atenção especial ao usar o OpenResty, que requer uma versão específica do LuaJIT para rodar corretamente. O OpenResty é baseado no branch LuaJIT 2.1 e fez muitas de suas extensões para o LuaJIT.
Então, ao rodar o código nesta coluna, lembre-se de usar a instalação oficial do OpenResty. Se você adicionar o lua-nginx-module
para compilar em cima do NGINX, você ainda vai cair em muitas armadilhas!
4. Confusão sobre valores nulos
P: Algumas coisas confusas que encontrei são ngx.null
, nil
, null
, e ""
. Quando pesquisei na web, vi que alguém disse que null
é uma definição de ngx.null
. Quando o Redis retorna, muitas vezes determina se o resultado retornado é nulo ou não, então com qual valor ele é comparado ao fazer a determinação? Há outras armadilhas sobre o uso desses valores? Não entendo esses valores claramente.
R: Antes de responder sua pergunta, sugiro que você use o seguinte código para encontrar uma chave em lua-resty-redis
.
local res, err = red:get("dog")
Isso porque o nil do Lua não pode ser usado como valor da tabela, então o OpenResty introduz ngx.null
como o valor nulo na tabela.
Podemos imprimir ngx.null
e seu tipo com o seguinte código.
# imprimir ngx.null
$ resty -e 'print(ngx.null)'
null
# Imprimir o tipo
$ resty -e 'print(type(ngx.null))'
userdata
Como você pode ver, ngx.null
não é nil
, mas é do tipo userdata
.
Além disso, há muitos valores nulos no OpenResty, como cjson.null
, cdata``:NULL
e assim por diante, que discutirei mais tarde.
Os únicos valores falsos no OpenResty são nil
e false
. Então, quando você escreve código como if not res then
, você deve ter cuidado, e é melhor mudar para explícito if res ~= nil and res ~= false then
, com algo assim, e com cobertura de caso de teste correspondente.
5. O que exatamente é o gateway de API?
P: O que é o gateway de API que foi mencionado no artigo? E NGINX, Tomcat, Apache e outros servidores web?
R: O gateway de API é um gateway usado para gerenciar serviços de forma unificada. Por exemplo, pagamento, login de usuário, etc., são todos serviços fornecidos na forma de APIs, e todos precisam de um gateway para fazer segurança e autenticação unificadas.
O gateway de API pode substituir o NGINX tradicional, Apache para lidar com tráfego norte-sul, mas também no ambiente de microsserviços para lidar com tráfego leste-oeste, é um middleware mais próximo do negócio, em vez do servidor Web subjacente.
Para mais informações sobre a introdução e implementação do gateway de API, consulte o Apache APISIX; Apache APISIX é baseado na implementação do OpenResty.