¿Cómo gestionar paquetes de terceros de OpenResty a través de LuaRocks y OPM?

API7.ai

September 17, 2022

OpenResty (NGINX + Lua)

En la publicación anterior, obtuvimos una visión general de algunos proyectos oficiales de OpenResty. Sin embargo, si usamos OpenResty en un entorno de producción, estas bibliotecas que vienen con el paquete de OpenResty son insuficientes. Por ejemplo, no hay una biblioteca lua-resty para enviar solicitudes HTTP, y no hay forma de interactuar con Kafka.

Entonces, ¿qué debemos hacer?

Debido a que OpenResty no es un fork de NGINX, ni es un reempaquetado de NGINX con algunas bibliotecas estándar, sino que simplemente utiliza NGINX como la biblioteca de red subyacente.

Cuando usas NGINX, no estás pensando en cómo iniciar solicitudes HTTP personalizadas o cómo interactuar con Kafka. Y en el mundo de OpenResty, gracias a cosocket, los desarrolladores pueden escribir rápidamente lua-resty-http y lua-resty-kafka para manejar estas necesidades, al igual que lo harías con lenguajes de desarrollo como Python, PHP, etc.

Otro consejo para ti: no deberías usar ninguna biblioteca del mundo de Lua para resolver los problemas mencionados, sino utilizar las bibliotecas lua-resty-* basadas en cosocket. Las bibliotecas del mundo de Lua probablemente introducirán bloqueos, lo que reduciría drásticamente el rendimiento de un servicio que de otro modo sería de alto rendimiento. Este es un error común entre los principiantes de OpenResty y no es fácil de detectar.

Entonces, ¿cómo encontramos estas bibliotecas lua-resty-* no bloqueantes? A continuación, te presentaré algunas formas.

OPM

OPM (OpenResty Package Manager) es el gestor de paquetes que viene con OpenResty y puede usarse después de haber instalado OpenResty. Podemos intentar encontrar la biblioteca que envía solicitudes HTTP usando el comando opm search http.

La primera consulta puede ser lenta, generalmente toma unos segundos. opm.openresty.org realizará una consulta en la base de datos PostgreSQL y almacenará en caché los resultados por un tiempo.

openresty/lua-resty-upload                            Lector y analizador de streaming para la subida de archivos HTTP basado en ngx_lua cosocket

Cuando ves este resultado, podrías preguntarte: ¿qué tiene que ver este paquete lua-resty-upload con el envío de HTTP?

Resulta que cuando OPM buscó, buscó tanto en el nombre del paquete como en la descripción del paquete usando la palabra clave. Es por eso que la búsqueda anterior tarda unos segundos. Realiza una búsqueda de texto completo en la cadena dentro de PostgreSQL.

Pero, de todos modos, este resultado no es amigable. Modifiquemos la palabra clave y busquemos de nuevo.

$ opm search lua-resty-http

ledgetech/lua-resty-http                          Cliente HTTP Lua basado en cosocket para OpenResty/ngx_lua
pintsized/lua-resty-http                          Cliente HTTP Lua basado en cosocket para OpenResty/ngx_lua
agentzh/lua-resty-http                            Cliente HTTP Lua basado en cosocket para OpenResty/ngx_lua

En el mundo de OpenResty, si implementas un paquete usando cosocket, debes usar el prefijo lua-resty, lo cual es una regla no escrita.

Al revisar los resultados de la búsqueda, OPM utiliza la dirección del repositorio de GitHub del contribuyente como el nombre del paquete, es decir, ID de GitHub / nombre del repositorio. Devuelve tres bibliotecas de terceros lua-resty-http. ¿Cuál deberíamos elegir?

Antes de elegir el paquete, veamos su cantidad de estrellas y la última fecha de actualización: solo una docena de estrellas; la última actualización fue en 2016. Este es un proyecto abandonado. Profundizando más, pintsized/lua-resty-http y ledgetech/lua-resty-http apuntan al mismo repositorio. Así que no importa cuál elijas, es lo mismo.

Además, el sitio web de OPM es relativamente simple y no proporciona el número de descargas del paquete ni las dependencias de este paquete. Sería útil si dedicaras más tiempo a averiguar qué bibliotecas lua-resty son las correctas para usar, cuando eso debería ser el trabajo del mantenedor.

LuaRocks

LuaRocks es otro gestor de paquetes para el mundo de OpenResty, nacido antes que OPM. A diferencia de OPM, que contiene solo paquetes relacionados con OpenResty, LuaRocks también tiene bibliotecas del mundo de Lua. Por ejemplo, LuaSQL-MySQL en LuaRocks es un paquete que se conecta a MySQL en el mundo de Lua y no se puede usar en OpenResty.

Siguiendo con el ejemplo de la biblioteca HTTP, intentemos usar LuaRocks para buscar.

$ luarocks search http

Como puedes ver, también devuelve una gran cantidad de paquetes.

Podríamos cambiar la palabra clave de nuevo.

$ luarocks search lua-resty-http

Esta vez solo se devolvió un paquete. Podemos ir al sitio web de LuaRocks y ver los detalles de este paquete. Aquí hay una captura de pantalla de la página del sitio web.

Detalles del paquete en LuaRocks

La captura de pantalla anterior contiene el autor, la licencia, la URL de GitHub, el número de descargas, un resumen de características, el historial de versiones, las dependencias, etc. A diferencia de OPM, LuaRocks no utiliza directamente la información de GitHub, sino que requiere que los desarrolladores se registren en LuaRocks por separado.

El proyecto de API gateway de código abierto, Apache APISIX, utiliza LuaRocks para la gestión de paquetes. Examinemos brevemente cómo está escrita la configuración de gestión de paquetes de APISIX.

La última versión de APISIX es 2.15, y puedes encontrar el archivo apisix-2.15.0-0.rockspec en el proyecto Apache APISIX.

package = "apisix"
version = "2.15.0-0"
supported_platforms = {"linux", "macosx"}

source = {
    url = "git://github.com/apache/apisix",
    branch = "2.15.0",
}

description = {
    summary = "Apache APISIX es un API gateway nativo de la nube para microservicios, ofreciendo el máximo rendimiento, seguridad, código abierto y una plataforma escalable para todas tus APIs y microservicios.",
    homepage = "https://github.com/apache/apisix",
    license = "Apache License 2.0",
}

dependencies = {
    "lua-resty-ctxdump = 0.1-0",
    "lua-resty-dns-client = 6.0.2",
    "lua-resty-template = 2.0",
    "lua-resty-etcd = 1.8.2",
    "api7-lua-resty-http = 0.2.0",
    "lua-resty-balancer = 0.04",
    "lua-resty-ngxvar = 0.5.2",
    "lua-resty-jit-uuid = 0.0.7",
    "lua-resty-healthcheck-api7 = 2.2.0",
    "api7-lua-resty-jwt = 0.2.4",
    "lua-resty-hmac-ffi = 0.05",
    "lua-resty-cookie = 0.1.0",
    "lua-resty-session = 3.10",
    "opentracing-openresty = 0.1",
    "lua-resty-radixtree = 2.8.2",
    "lua-protobuf = 0.3.4",
    "lua-resty-openidc = 1.7.5",
    "luafilesystem = 1.7.0-2",
    "api7-lua-tinyyaml = 0.4.2",
    "nginx-lua-prometheus = 0.20220527",
    "jsonschema = 0.9.8",
    "lua-resty-ipmatcher = 0.6.1",
    "lua-resty-kafka = 0.20-0",
    "lua-resty-logger-socket = 2.0.1-0",
    "skywalking-nginx-lua = 0.6.0",
    "base64 = 1.5-2",
    "binaryheap = 0.4",
    "api7-dkjson = 0.1.1",
    "resty-redis-cluster = 1.02-4",
    "lua-resty-expr = 1.3.1",
    "graphql = 0.0.2",
    "argparse = 0.7.1-1",
    "luasocket = 3.0rc1-2",
    "luasec = 0.9-1",
    "lua-resty-consul = 0.3-2",
    "penlight = 1.9.2-1",
    "ext-plugin-proto = 0.5.0",
    "casbin = 1.41.1",
    "api7-snowflake = 2.0-1",
    "inspect == 3.1.1",
    "lualdap = 1.2.6-1",
    "lua-resty-rocketmq = 0.3.0-0",
    "opentelemetry-lua = 0.1-3",
    "net-url = 0.9-1",
    "xml2lua = 1.5-2",
    "nanoid = 0.1-1",
    "lua-resty-mediador = 0.1.2-1"
}

build = {
    type = "make",
    build_variables = {
        CFLAGS="$(CFLAGS)",
        LIBFLAG="$(LIBFLAG)",
        LUA_LIBDIR="$(LUA_LIBDIR)",
        LUA_BINDIR="$(LUA_BINDIR)",
        LUA_INCDIR="$(LUA_INCDIR)",
        LUA="$(LUA)",
        OPENSSL_INCDIR="$(OPENSSL_INCDIR)",
        OPENSSL_LIBDIR="$(OPENSSL_LIBDIR)",
    },
    install_variables = {
        ENV_INST_PREFIX="$(PREFIX)",
        ENV_INST_BINDIR="$(BINDIR)",
        ENV_INST_LIBDIR="$(LIBDIR)",
        ENV_INST_LUADIR="$(LUADIR)",
        ENV_INST_CONFDIR="$(CONFDIR)",
    },
}

Como puedes ver en el archivo, las dependencias están mezcladas con bibliotecas lua-resty-* y bibliotecas del mundo puro de Lua, que solo pueden instalarse parcialmente usando OPM. Después de escribir la configuración, usa el comando de carga de LuaRocks para subir esta configuración, y el usuario puede usar LuaRocks para descargar e instalar APISIX.

LuaRocks admite esto. Puedes especificar la ruta y el nombre del código fuente C en el archivo .rockspec, y LuaRocks lo compilará localmente por ti. OPM aún no admite esta función.

awesome-resty

El proyecto awesome-resty mantiene casi todos los paquetes disponibles para OpenResty, organizados en categorías. Este es el mejor lugar al que acudir cuando no estás seguro de si existe un paquete de terceros adecuado.

Tomemos la biblioteca HTTP como ejemplo. En awesome-resty, naturalmente pertenece a la categoría networking.

lua-resty-http by @pintsized — Cliente HTTP Lua basado en cosocket para OpenResty / ngx_lua
lua-resty-http by @liseen — Cliente HTTP Lua para ngx_lua basado en la API de cosocket
lua-resty-http by @DorianGray — Cliente HTTP Lua para ngx_lua basado en la API de cosocket
lua-resty-http-simple — Cliente HTTP Lua simple para ngx_lua
lua-resty-httpipe — Cliente HTTP Lua basado en cosocket para OpenResty / ngx_lua
lua-resty-httpclient — Biblioteca de cliente HTTP Lua no bloqueante para aLiLua & ngx_lua
lua-httpcli-resty — Módulo de cliente HTTP Lua para OpenResty
lua-resty-requests — Otra biblioteca HTTP para OpenResty

Vemos que hay ocho bibliotecas de terceros para lua-resty-http. Comparando con los resultados anteriores, solo encontramos 2 usando OPM y solo 1 en LuaRocks. Sin embargo, si es difícil elegir, usa la primera, que es la misma que la de LuaRocks.

Para los ingenieros dispuestos a experimentar, recomiendo la última biblioteca: lua-resty-requests, una biblioteca de acceso HTTP más amigable con el mismo estilo de interfaz que el famoso Requests de Python. Si eres un amante de Python como yo, te encantará lua-resty-requests, que es creada por tokers, un miembro activo de la comunidad de OpenResty, por lo que puedes usarla con confianza.

Resumen

Para que un proyecto de código abierto prospere, no solo necesita tecnología sólida, buena documentación y pruebas completas, sino también un ecosistema que reúna a más desarrolladores y empresas. Como dice el Apache Way: la comunidad sobre el código.

No hay material de aprendizaje sistemático para OpenResty, no hay una guía de código oficial, y muchos puntos de optimización se han escrito en el proyecto de código abierto. Aún así, la mayoría de los desarrolladores saben de qué están hablando pero no saben por qué. Ese es el propósito de este libro electrónico. Después de aprenderlo, espero que puedas escribir un código OpenResty más eficiente y participar de manera más eficiente en proyectos de código abierto relacionados con OpenResty, por ejemplo, Apache APISIX.

¿Qué opinas sobre el ecosistema de OpenResty? No dudes en dejar un comentario y hablemos al respecto. Además, te invito a compartir este artículo.