¿Qué sucede si hay un conflicto entre las reglas de Lua y la configuración de NGINX?
API7.ai
October 13, 2022
1. El nombre y el lenguaje de OpenResty
P: Hasta ahora no he entendido el origen del nombre OpenResty. Además, OpenResty se desarrolla con el lenguaje Lua, ¿por qué no con otros lenguajes de scripting como Shell, etc.?
R: OpenResty comenzó como un proyecto corporativo de Yahoo! en octubre de 2007. El nombre "Open" proviene de OpenAPI, y "Resty" de rest API. Inicialmente, OpenResty no estaba destinado a ser un servidor web y una plataforma de desarrollo, sino una aplicación como un sitio web.
Cuando OpenResty se convirtió en código abierto hace más de una década, muy pocos lenguajes admitían la programación síncrona no bloqueante. Incluso ahora, no muchos lenguajes de back-end pueden alcanzar este nivel de rendimiento con OpenResty. Actualmente, más desarrolladores están utilizando OpenResty en puertas de enlace API y WAFs soft, lo cual es una elección natural para los desarrolladores.
En cuanto al lenguaje, OpenResty no es el único proyecto que integra otros lenguajes de desarrollo en NGINX. Por ejemplo, NGINX integra oficialmente JS; también hay proyectos de código abierto que integran PHP en NGINX.
Normalmente, la elección del lenguaje se basa en factores como la concurrencia, JIT y la popularidad del lenguaje. Para OpenResty, en 2007, Lua era sin duda la mejor opción. OpenResty tomó un desvío al elegir perl en lugar de Lua en sus primeras versiones.
2. La prioridad de las reglas de configuración
P: Cuando las reglas de Lua en OpenResty entran en conflicto con la configuración de NGINX, por ejemplo, si NGINX tiene reglas de rewrite configuradas y al mismo tiempo se hace referencia a rewrite_by_lua_file
, ¿cuál es la prioridad de estas dos reglas?
R: En realidad, depende de cómo esté escrita la regla de rewrite en la configuración de NGINX, ya sea break
o last
, como se indica en la documentación oficial de OpenResty, con un código de ejemplo:
location /foo {
rewrite ^ /bar;
rewrite_by_lua 'ngx.exit(503)';
}
location /bar {
...
}
En esta configuración del código de ejemplo, ngx.exit(503)
no se ejecutará.
Sin embargo, si lo escribes de la siguiente manera, ngx.exit(503)
se ejecutará.
rewrite ^ /bar break.
Sin embargo, recomiendo usar OpenResty para rewrite en lugar de la configuración de NGINX. Para evitar esta ambigüedad, mucha configuración de NGINX es relativamente oscura y requiere que consultes la documentación para entenderla repetidamente.
3. ¿Por qué mi código da error?
P: En la función de tabla de la extensión de LuaJIT, ¿por qué las siguientes dos líneas de código dan un error "módulo no encontrado" cuando las ejecuta LuaJIT? Estoy usando LuaJIT versión 2.0.5.
local new_tab = require('table.new')
# o
require('table.clear')
# La ejecución dará error
luajit: table_luajit.lua:1: module 'table.new' not found:
R: Estas dos líneas de código requieren LuaJIT versión 2.1 para ejecutarse, como se documenta aquí: https://github.com/LuaJIT/LuaJIT/blob/v2.1/doc/extensions.html#L218, puedes consultarlo.
Como mencionamos, debes prestar especial atención al usar OpenResty, ya que requiere una versión específica de LuaJIT para funcionar correctamente. OpenResty se basa en la rama LuaJIT 2.1 y ha hecho muchas extensiones propias a LuaJIT.
Por lo tanto, al ejecutar el código en esta columna, recuerda usar la instalación oficial de OpenResty. Si agregas el lua-nginx-module
para compilar sobre NGINX, ¡aún te encontrarás con muchos problemas!
4. Confusión sobre valores nulos
P: Algunas cosas confusas que he encontrado son ngx.null
, nil
, null
y ""
. Cuando busqué en la web, vi que alguien dijo que null
es una definición de ngx.null
. Cuando Redis devuelve un valor, a menudo se determina si el resultado devuelto es nulo o no, ¿con qué valor se compara al hacer esta determinación? ¿Hay otras trampas en el uso de estos valores? No entiendo claramente estos valores.
R: Antes de responder a tu pregunta, te sugiero que uses el siguiente código para buscar una clave en lua-resty-redis
.
local res, err = red:get("dog")
Esto se debe a que el nil de Lua no puede usarse como valor en una tabla, por lo que OpenResty introduce ngx.null
como valor nulo en la tabla.
Podemos imprimir ngx.null
y su tipo con el siguiente código.
# imprimir ngx.null
$ resty -e 'print(ngx.null)'
null
# Imprimir el tipo
$ resty -e 'print(type(ngx.null))'
userdata
Como puedes ver, ngx.null
no es nil
, sino de tipo userdata
.
Además, hay muchos valores nulos en OpenResty, como cjson.null
, cdata:NULL
, etc., que discutiré más adelante.
Los únicos valores falsos en OpenResty son nil
y false
. Por lo tanto, cuando escribes código como if not res then
, debes tener cuidado, y es mejor cambiarlo a algo explícito como if res ~= nil and res ~= false then
, con algo así, y con cobertura de casos de prueba correspondientes.
5. ¿Qué es exactamente la puerta de enlace API?
P: ¿Qué es la puerta de enlace API que se ha mencionado en el artículo? ¿Y NGINX, Tomcat, Apache y otros servidores web?
R: La puerta de enlace API es una puerta de enlace utilizada para gestionar servicios de manera unificada. Por ejemplo, pagos, inicio de sesión de usuarios, etc., son servicios proporcionados en forma de APIs, y todos necesitan una puerta de enlace para realizar seguridad y autenticación unificadas.
La puerta de enlace API puede reemplazar a los tradicionales NGINX y Apache para manejar el tráfico norte-sur, pero también en entornos de microservicios para manejar el tráfico este-oeste, es un middleware más cercano al negocio que un servidor web subyacente.
Para obtener más información sobre la introducción e implementación de la puerta de enlace API, consulta Apache APISIX; Apache APISIX está basado en la implementación de OpenResty.