global-throttle: Control de flujo de propósito general con soporte de almacenamiento compartido
Instalación
Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.
CentOS/RHEL 7 o Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-global-throttle
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-global-throttle
Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.
Este documento describe lua-resty-global-throttle v0.2.0 lanzado el 30 de diciembre de 2020.
Uso
Una implementación de limitación de velocidad genérica y distribuida para Openresty. Se puede utilizar para limitar cualquier acción, ya sea una solicitud o una llamada a función. Actualmente, solo se ha implementado la limitación de tasa de ventana deslizante aproximada.
Primero, requiere el módulo:
local global_throttle = require "resty.global_throttle"
Después de eso, puedes crear una instancia de limitación como la siguiente, donde 100 es el límite que se aplicará por cada ventana de 2 segundos. El tercer parámetro le indica al limitador qué proveedor de almacenamiento debe usar para almacenar sus estadísticas internas.
local memc_host = os.getenv("MEMCACHED_HOST")
local memc_port = os.getenv("MEMCACHED_PORT")
...
local my_throttle, err = global_throttle.new(namespace, 10, 2, {
provider = "memcached",
host = memc_host,
port = memc_port,
connect_timeout = 15,
max_idle_timeout = 10000,
pool_size = 100,
})
Finalmente, llamas a lo siguiente cada vez antes de lo que sea que estés limitando:
local estimated_final_count, desired_delay, err = my_throttle:process("identifier of whatever it is your are throttling")
Cuando desired_delay existe, significa que se está excediendo el límite y el cliente debe ser limitado durante desired_delay segundos.
Para una comprensión más completa de cómo usar esta biblioteca, consulta el directorio examples.
Consideraciones para producción
- Asegúrate de configurar correctamente el tamaño del grupo de conexiones. Básicamente, si tu almacenamiento (es decir, memcached) puede manejar
nconexiones concurrentes y tu NGINX tienemtrabajadores, entonces el tamaño del grupo de conexiones debe configurarse comon/m. Eso se debe a que el tamaño del grupo configurado es por trabajador de NGINX. Por ejemplo, si tu almacenamiento generalmente maneja 1000 solicitudes concurrentes y tienes 10 trabajadores de NGINX, entonces el tamaño del grupo de conexiones debe ser 100. De manera similar, si tienespinstancias diferentes de NGINX, entonces el tamaño del grupo de conexiones debe sern/m/p. - Ten cuidado al tomar decisiones de caché basadas en
desired_delay, a veces es tan pequeño que tu caché puede interpretarlo como 0 y almacenar indefinidamente. Además, almacenar durante muy poco tiempo probablemente no aporta ningún beneficio.
Contribuciones y desarrollo
La biblioteca está diseñada para ser extensible. Actualmente, solo se ha implementado el algoritmo de ventana deslizante aproximada en lib/resty/global_throttle/sliding_window.lua. Se puede usar como un punto de referencia para implementar otros algoritmos.
Los proveedores de almacenamiento están implementados en lib/resty/global_throttle/store/.
Referencias
- Publicación del blog de Cloudflare sobre ventanas deslizantes aproximadas: https://blog.cloudflare.com/counting-things-a-lot-of-different-things/
GitHub
Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-global-throttle.