Subproyectos detrás de OpenResty
API7.ai
September 12, 2022
¿Cómo extraer código Lua de nginx.conf
y mantenerlo legible y mantenible? La solución es bastante simple. Veamos cómo implementarlo con OpenResty.
Primero, crea un directorio llamado lua
. Luego, colocaremos todos los archivos .lua
en él.
$ mkdir lua
$ cat lua/hello.lua
ngx.say("hello, world")
Segundo, usa content_by_lua_block
para reemplazar content_by_lua_file
en el archivo nginx.conf
.
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
content_by_lua_file lua/hello.lua;
}
}
}
Tercero, reinicia los servicios de OpenResty, ¡y listo!
$ sudo kill -HUP `cat logs/nginx.pid`
Usando content_by_lua_file
, podríamos actualizar el archivo Lua directamente en lugar de actualizar nginx.conf
. Pero surgen algunas preguntas:
- Usamos una ruta relativa en la sección
content_by_lua_file lua/hello.lua
. ¿Cómo encuentra OpenResty el archivo Lua real? - Después de modificar el código Lua, necesitamos reiniciar OpenResty para que funcione. ¿Hay alguna manera de depurar de manera eficiente?
- ¿Cómo agregar el directorio que contiene los archivos Lua a la ruta de búsqueda de OpenResty?
Te animo a que pienses en estas preguntas, ya que todas pueden responderse en la documentación oficial. Por eso siempre enfatizo la importancia de la documentación.
Para la primera pregunta, si se proporciona una ruta relativa, cuando OpenResty se inicia, prefijará el -p PATH
en los parámetros de la línea de comandos de inicio de OpenResty y concatenará la ruta relativa en una ruta absoluta. De esta manera, OpenResty puede encontrar el archivo Lua sin problemas.
El segundo problema es que el código Lua se carga en la primera solicitud y se almacena en caché por defecto. Por lo tanto, cada vez que cambias el archivo fuente Lua, debes recargar OpenResty para que funcione. Puedes evitar la recarga desactivando lua_code_cache
en nginx.conf
. Sin embargo, es esencial tener en cuenta que este método solo debe usarse temporalmente para desarrollo y depuración. Si estás implementando en producción, debes habilitar la caché. De lo contrario, tendrá un impacto significativo en el rendimiento.
Para la última pregunta, OpenResty proporciona una directiva lua_package_path
para establecer la ruta de búsqueda de módulos Lua. Por ejemplo, podemos configurar lua_package_path
como $prefix/lua/?.lua;;
:
$prefix
es el-p PATH
en el parámetro de inicio./lua/?.lua
indica todos los archivos en el directorio Lua con el sufijo.lua
.- Los dos últimos puntos y comas representan la ruta de búsqueda de código incorporada.
Estructura del directorio después de la instalación
Después de entender el primer programa "hello world", profundicemos y veamos cómo es la estructura de directorios de OpenResty después de su instalación y qué archivos contiene.
Primero, pasamos la opción -V
para ver dónde está instalado OpenResty. Para el siguiente resultado, omití muchos parámetros de compilación de módulos, que agregaremos más adelante:
$ openresty -V
nginx version: openresty/1.13.6.2
built by clang 10.0.0 (clang-1000.10.44.4)
built with OpenSSL 1.1.0h 27 Mar 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/openresty/1.13.6.2/nginx ...
Yo uso brew para instalar OpenResty en mi Mac. La ruta es /usr/local/Cellar/openresty/1.13.6.2/nginx
, que puede diferir de tu entorno. Esta ruta contiene los directorios bin
, luajit
, lualib
, nginx
, pod
y otros. Es esencial entender el significado de estas carpetas para que podamos aprender OpenResty mejor. Así que echemos un vistazo a cada una de ellas.
Primero está el importante directorio bin
.
$ ll /usr/local/Cellar/openresty/1.13.6.2/bin
total 320
-r-xr-xr-x 1 ming admin 19K 3 27 12:54 md2pod.pl
-r-xr-xr-x 1 ming admin 15K 3 27 12:54 nginx-xml2pod
lrwxr-xr-x 1 ming admin 19B 3 27 12:54 openresty -> ../nginx/sbin/nginx
-r-xr-xr-x 1 ming admin 62K 3 27 12:54 opm
-r-xr-xr-x 1 ming admin 29K 3 27 12:54 resty
-r-xr-xr-x 1 ming admin 15K 3 27 12:54 restydoc
-r-xr-xr-x 1 ming admin 8.3K 3 27 12:54 restydoc-index
Aquí se encuentran tanto la CLI de OpenResty, resty
, que mencionamos en la sección anterior, como el ejecutable principal, openresty
, que en realidad es un enlace simbólico a nginx
. En cuanto a las otras herramientas en el directorio, no hay duda de que, como resty
, son todos scripts en Perl.
Entre ellos, opm
es una herramienta de gestión de paquetes que nos permite gestionar todo tipo de paquetes de terceros, lo cual cubriremos en una sección posterior; y restydoc
, un viejo amigo de la primera sección, es un visor de documentación proporcionado por OpenResty, que nos permite ver la documentación de OpenResty y NGINX.
$ restydoc -s ngx.say
$ restydoc -s proxy_pass
Los dos ejemplos anteriores consultan la API de OpenResty y los comandos de NGINX, respectivamente. restydoc
es una herramienta muy útil para que los ingenieros de backend se enfoquen en el desarrollo.
Después de explorar el directorio bin
, pasemos al directorio pod
.
Primero, enfaticemos que pod
aquí no tiene nada que ver con el concepto de un pod en Kubernetes. En cambio, pod
es un lenguaje de marcado utilizado en Perl para escribir documentación de módulos Perl. Este directorio contiene la documentación de OpenResty
, NGINX
, lua-resty-*
y LuaJIT
, que están todos vinculados con restydoc
mencionado anteriormente.
Luego están los familiares directorios NGINX
y luajit
. Estos dos son fáciles de entender. Principalmente almacenan los archivos ejecutables y dependencias de NGINX y LuaJIT, y son la base de OpenResty. Mucha gente dice que OpenResty está basado en Lua, pero eso es inexacto. Como vimos anteriormente, OpenResty en realidad está basado en LuaJIT.
De hecho, en las primeras etapas, OpenResty venía con Lua y LuaJIT, y podíamos decidir si usar Lua o LuaJIT mediante opciones de compilación. Sin embargo, Lua está siendo descontinuado, y solo se admite el más eficiente LuaJIT.
Finalmente, veamos el directorio lualib
. Contiene las bibliotecas Lua utilizadas en OpenResty, principalmente divididas en dos directorios: ngx
y resty
.
- El directorio
ngx
contiene los códigos Lua del proyecto oficial lua-resty-core, que es una reimplementación basada en FFI de la API de OpenResty. Explicaré en un capítulo especial por qué necesitamos reimplementarlo. - El directorio
resty
contiene códigos Lua de varios proyectoslua-resty-*
, que veremos a continuación.
Siguiendo la convención de este curso, en este punto proporcionaré la fuente de estos directorios. Esta es también una de las alegrías de los proyectos de código abierto. Si te gusta profundizar y preguntar hasta el final, siempre encontrarás cosas más interesantes.
Aquí está el script de empaquetado de OpenResty para CentOS, que contiene todos los directorios mencionados anteriormente.
%files
%defattr(-,root,root,-)
/etc/init.d/%{name}
/usr/bin/%{name}
%{orprefix}/bin/openresty
%{orprefix}/site/lualib/
%{orprefix}/luajit/*
%{orprefix}/lualib/*
%{orprefix}/nginx/html/*
%{orprefix}/nginx/logs/
%{orprefix}/nginx/sbin/*
%{orprefix}/nginx/tapset/*
%config(noreplace) %{orprefix}/nginx/conf/*
%{orprefix}/COPYRIGHT
Visión general del proyecto OpenResty
Cuando hablamos de OpenResty, pensamos en lua-nginx-module
. Sí, este módulo C de NGINX es realmente el núcleo de OpenResty, pero no es equivalente a OpenResty. Muchos ingenieros llaman a OpenResty como ngx + lua
, lo cual también se usa en libros compartidos y publicados en muchas conferencias técnicas. Esto no es riguroso y no es apoyado por la comunidad de OpenResty.
Permíteme hablar sobre por qué y qué otros proyectos relacionados, además de lua-nginx-module
, hay en OpenResty.
Abre la página principal del proyecto OpenResty en GitHub, y verás que OpenResty contiene 68 proyectos públicos, que se dividen aproximadamente en las siguientes siete categorías. Permíteme presentarlas brevemente para que tengas una impresión preliminar y puedas aprender rápidamente.
Módulos C de NGINX
La nomenclatura de los proyectos de OpenResty está estandarizada, y aquellos nombrados como *-nginx-module
son los módulos C de NGINX.
Hay más de 20 módulos C en OpenResty, y podemos encontrarlos usando openresty -V
, que usamos al comienzo de esta sección.
$ openresty -V
nginx version: openresty/1.13.6.2
built by clang 10.0.0 (clang-1000.10.44.4)
built with OpenSSL 1.1.0h 27 Mar 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/openresty/1.13.6.2/nginx --with-cc-opt='-O2 -I/usr/local/include -I/usr/local/opt/pcre/include -I/usr/local/opt/openresty-openssl/include' --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.13 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../ngx_stream_lua-0.0.5 --with-ld-opt='-Wl,-rpath,/usr/local/Cellar/openresty/1.13.6.2/luajit/lib -L/usr/local/lib -L/usr/local/opt/pcre/lib -L/usr/local/opt/openresty-openssl/lib' --pid-path=/usr/local/var/run/openresty.pid --lock-path=/usr/local/var/run/openresty.lock --conf-path=/usr/local/etc/openresty/nginx.conf --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-pcre-jit --with-ipv6 --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_geoip_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-dtrace-probes --with-stream --with-stream_ssl_module --with-http_ssl_module
Aquí --add-module=
es seguido por los módulos C de OpenResty. Los principales son lua-nginx-module
y stream-lua-nginx-module
, el primero para manejar tráfico de Capa 7 y el segundo para manejar tráfico de Capa 4.
Algunos de estos módulos C requieren atención especial y no se recomiendan, aunque están compilados en OpenResty por defecto. Por ejemplo, redis2-nginx-module
, redis-nginx-module
y memc-nginx-module
se usan para interoperar con Redis y Memcached. Estas bibliotecas C fueron recomendadas por OpenResty en las primeras etapas, pero han sido reemplazadas por lua-resty-redis
y lua-resty-memcached
después de que se agregó la función cosocket
, y se mantienen inactivas.
OpenResty no desarrollará más bibliotecas C de NGINX en el futuro, sino que se centrará en la biblioteca Lua basada en cosocket
, que es el futuro.
Bibliotecas lua-resty-*
El repositorio oficial de OpenResty contiene 18 bibliotecas lua-resty-*
, incluyendo Redis, MySQL, Memcached, WebSocket, DNS, control de tráfico, procesamiento de cadenas, caché en proceso y otras bibliotecas estándar. Además de las oficiales que vienen incluidas, hay más bibliotecas de terceros. Son esenciales, y dedicaremos más tiempo a estas bibliotecas en la siguiente sección.
Rama de LuaJIT mantenida por OpenResty
OpenResty mantiene su propia rama de LuaJIT además de su parche de OpenSSL. En 2015, el autor de LuaJIT, Mike Pall, anunció su retiro para encontrar un nuevo mantenedor de LuaJIT, pero Mike no encontró un mantenedor adecuado. Ahora se dedica principalmente a la corrección de errores, y el desarrollo de nuevas funciones se ha suspendido, por lo que OpenResty mantiene su propia rama de LuaJIT.
En comparación con Lua, LuaJIT agrega muchas funciones esenciales y únicas, pero no muchos ingenieros las conocen, por lo que son habilidades semiocultas que presentaré más adelante.
Marco de pruebas
El marco de pruebas de OpenResty es test-nginx, también desarrollado en Perl, y como puedes ver por el nombre, está diseñado específicamente para probar proyectos relacionados con NGINX. Todos los casos de prueba oficiales de OpenResty para módulos C y la biblioteca lua-resty
son impulsados por test-nginx
. Este es un sistema mucho más potente e independiente, a diferencia de los marcos comunes basados en aserciones.
Algunos contribuyentes de OpenResty tampoco han entendido este marco de pruebas y, a veces, envían PRs que contienen código C y Lua complejo, pero aún así a menudo se sienten intimidados por la idea de escribir casos de prueba correspondientes. Así que si has visto algunos de los casos de prueba en el directorio /t
del proyecto OpenResty y aún estás confundido, no dudes de ti mismo. La mayoría de las personas están en la misma situación.
Además de test-nginx
, el proyecto mockeagain simula una red lenta, permitiendo que los programas lean y escriban un byte a la vez. Esta es una herramienta muy útil para servidores web.
Cadena de herramientas de depuración
El proyecto OpenResty ha invertido mucho esfuerzo en cómo depurar código de manera científica y dinámica.
Los dos proyectos de OpenResty, openresty-systemtap-toolkit y stapxx, están basados en systemtap
, una herramienta de depuración y seguimiento dinámico. La mayor ventaja de usar systemtap
es que permite el análisis in vivo mientras es completamente no intrusivo para la aplicación objetivo.
Por ejemplo, un systemtap
es como ir al hospital y hacerse una tomografía computarizada, indolora y no perceptible. Aún mejor, systemtap
puede generar gráficos de llamadas visuales para el análisis de rendimiento, lo cual describiré más adelante, así que aquí tienes un gráfico de llamadas para que te hagas una idea.
Empaquetado
Los scripts de empaquetado de OpenResty en diferentes sistemas operativos de distribución (como CentOS, Ubuntu, macOS, etc.) están escritos a mano para una mejor controlabilidad. Cuando presentamos la estructura del directorio después de la instalación, ya cubrimos estos proyectos relacionados con el empaquetado: openresty-packaging y home-brew. Si estás interesado en esto, puedes aprenderlo por tu cuenta, y no lo repetiré aquí.
Herramientas de ingeniería
Además de estos proyectos más grandes, OpenResty tiene varias herramientas de ingeniería que en su mayoría están ocultas.
Por ejemplo, openresty-devel-utils es el conjunto de herramientas para desarrollar OpenResty y NGINX. Por supuesto, también están desarrolladas en Perl, y la mayoría de las herramientas no están documentadas. Pero para los desarrolladores de OpenResty, estas herramientas son muy útiles. Comenzaré seleccionando algunas y presentándolas brevemente.
- lj-releng es una herramienta de inspección de código LuaJIT simple y efectiva, similar a
luacheck
, que puede encontrar problemas potenciales con variables globales. - reindex, que significa reconstruir el índice, es una herramienta para formatear casos de prueba de
test-nginx
, reorganizar números de casos de prueba y eliminar espacios en blanco adicionales.reindex
es una de las herramientas que los desarrolladores de OpenResty usan a diario. - opsboy se utiliza para realizar implementaciones automatizadas. Se utiliza para implementar y ejecutar las pruebas de regresión que OpenResty realiza en clústeres de AWS EC2 antes de cada lanzamiento. Para obtener información detallada, puedes consultar la documentación oficial.
opsboy
es un DSL implementado en Perl. A los autores de OpenResty les gusta crear diferentes DSLs para resolver problemas.
Resumen
Hoy, principalmente aprendimos la estructura del directorio de OpenResty después de la instalación y algunos subproyectos detrás de él. Después de aprender el contenido de hoy, espero que puedas conocer más sobre los proyectos de OpenResty. OpenResty ha ido mucho más allá del alcance del equilibrio de carga y proxy inverso de NGINX y ha creado su propio ecosistema. La próxima vez hablaremos de esto en detalle.