Lo que debes saber sobre la limitación de velocidad

Lo imprescindible que debes saber sobre la limitación de velocidad

Rate limiting es el concepto de controlar la cantidad de tráfico que se envía a un recurso. ¿Cómo se puede lograr este control? Mediante un limitador de velocidad: un componente que te permite controlar la velocidad del tráfico de red hacia un servidor API u otra aplicación que deseas proteger.

Esta es una visión general de cómo se sitúa un limitador de velocidad en el contexto de un sistema.

Por ejemplo, si un cliente envía 3 solicitudes a un servidor pero el servidor solo puede manejar 2 solicitudes, puedes usar un limitador de velocidad para restringir la solicitud adicional y evitar que llegue al servidor.

La necesidad de limitar la velocidad

Algunas de las principales razones para tener límites de velocidad en tu sistema son las siguientes:

  • Prevenir el abuso del sistema por parte de actores malintencionados que intentan abrumar tus servidores con un número inusualmente grande de solicitudes.
  • Solo permitir tráfico que tus servidores puedan manejar en cualquier momento dado.
  • Limitar el consumo de recursos costosos de un sistema externo.
  • Prevenir fallas en cascada en sistemas secundarios cuando el sistema de nivel superior se ve interrumpido por un gran número de solicitudes.

Conceptos clave de la limitación de velocidad

Hay 3 conceptos clave compartidos por cada configuración de limitación de velocidad. No importa qué tipo de algoritmo de limitación de velocidad adoptes, estos 3 conceptos entran en juego.

Veamos rápidamente cada uno de ellos.

  1. Límite – Define el número máximo de solicitudes permitidas por el sistema en un lapso de tiempo determinado. Por ejemplo, Twitter (ahora X) recientemente limitó a los usuarios no verificados a ver solo 600 tweets por día.
  2. Intervalo – Este es el período de tiempo para el límite. Puede ser desde segundos hasta minutos e incluso días.
  3. Identificador – Es un atributo único que te permite distinguir entre los propietarios de las solicitudes individuales. Por ejemplo, cosas como un ID de usuario o una dirección IP pueden desempeñar el papel de un identificador.

Diseñar un sistema con limitación de velocidad

La premisa básica de un limitador de velocidad es bastante simple. En términos generales, se cuenta el número de solicitudes enviadas por un usuario específico, una dirección IP o desde una ubicación geográfica. Si la cuenta supera el límite permitido, se rechaza la solicitud.

Sin embargo, en el trasfondo, hay varias consideraciones que deben tenerse en cuenta al diseñar un limitador de velocidad. Por ejemplo:

  • ¿Dónde deberías almacenar los contadores?
  • ¿Y qué hay de las reglas de limitación de velocidad?
  • ¿Cómo responder a las solicitudes rechazadas?
  • ¿Cómo asegurarse de que se aplican los cambios en las reglas?
  • ¿Cómo garantizar que la limitación de velocidad no degrade el rendimiento general de la aplicación?

Para equilibrar todas estas consideraciones, necesitas varias piezas que funcionen en combinación entre sí. Aquí tienes una ilustración que representa este tipo de sistema.

Vamos a entender qué está sucediendo aquí:

  • Cuando una solicitud llega al servidor API, primero pasa por el componente limitador de velocidad. El limitador de velocidad verifica las reglas en el motor de reglas.
  • A continuación, el limitador de velocidad verifica los datos de limitación de velocidad almacenados en la caché. Estos datos básicamente indican cuántas solicitudes se han atendido para un usuario específico o una dirección IP. La razón de usar una caché es lograr un alto rendimiento.
  • Si la solicitud se encuentra dentro del umbral aceptable, el limitador de velocidad la permite llegar al servidor API.
  • Si la solicitud excede el límite, el limitador de velocidad rechaza la solicitud e informa al cliente o al usuario que se les ha aplicado la limitación de velocidad. Una forma común es devolver el código de estado HTTP 429 (demasiadas solicitudes).

Mejoras posibles

Existen un par de mejoras que puedes realizar aquí:

  • Primero, en lugar de devolver el código de estado HTTP 429, también puedes simplemente descartar una solicitud en silencio. Este es un truco útil para engañar a un atacante haciéndolo creer que la solicitud ha sido aceptada, incluso cuando el limitador de velocidad ha descartado la solicitud por completo.
  • Segundo, también podrías tener una caché frente al motor de reglas para aumentar el rendimiento. En caso de actualizaciones en las reglas, podrías tener un proceso de trabajo en segundo plano que actualice la caché con el último conjunto de reglas.

Algoritmos de limitación de velocidad

Aunque cada algoritmo requiere una discusión detallada, aquí echaremos un vistazo a los más populares de manera breve.

Contador de Ventana Fija

Este es probablemente el algoritmo de limitación de velocidad más simple que existe. En este algoritmo, dividimos el tiempo en ventanas de tiempo fijas. Para cada ventana, mantenemos un contador. Cada solicitud entrante incrementa el contador en uno y cuando el contador alcanza el límite máximo, las solicitudes subsiguientes se descartan hasta que comienza una nueva ventana de tiempo.

Aunque este algoritmo es simple y fácil de entender, tiene un gran problema. Un pico de tráfico en los extremos de la ventana de tiempo puede hacer que pase un gran número de solicitudes en un corto período de tiempo y abrumar al servidor.

Si estás interesado, echa un vistazo a mi publicación sobre la implementación básica del algoritmo de limitación de velocidad de ventana fija.

Registro de Ventana Deslizante

El registro de ventana deslizante resuelve el problema con el algoritmo de ventana fija. En lugar de tener una ventana de tiempo fija, mantiene una ventana de tiempo deslizante.

Para cada solicitud, el algoritmo realiza un seguimiento de la marca de tiempo de la solicitud dentro de una caché. Cuando llega una nueva solicitud, se eliminan todas las marcas de tiempo obsoletas que son anteriores al comienzo de la ventana de tiempo actual. Si el tamaño del registro está dentro del límite permitido, se acepta la solicitud. De lo contrario, se rechaza.

Por supuesto, este algoritmo sufre del problema de consumir mucha memoria porque tienes que realizar un seguimiento de todas las marcas de tiempo.

Contador de Ventana Deslizante

El contador de ventana deslizante combina lo mejor de la ventana fija y la ventana deslizante.

En lugar de almacenar marcas de tiempo, este algoritmo mantiene un contador para una ventana deslizante. Para determinar si se debe aceptar o descartar una nueva solicitud, básicamente calcula la suma de las solicitudes en la ventana actual y la agrega a la aproximación de las solicitudes en la ventana anterior. La aproximación de las solicitudes en la ventana anterior se calcula multiplicando el número total de solicitudes en la ventana anterior por el porcentaje de superposición de la ventana deslizante.

La ventaja de este algoritmo es que suaviza los picos de tráfico y es eficiente en términos de memoria. Sin embargo, no calcula un número exacto de solicitudes, sino que maneja una aproximación.

Cubo de Tokens

El algoritmo del cubo de tokens es un algoritmo bastante popular para la limitación de velocidad.

En este algoritmo, creamos un cubo de tokens con una capacidad predefinida. Los tokens se colocan en el cubo a una velocidad preestablecida. Una vez que el cubo está lleno, no se agregan más tokens. Cuando llega una nueva solicitud, consume un token. Si no hay tokens disponibles en el cubo, el limitador de velocidad descarta la solicitud.

El beneficio de este enfoque es que permite que se realice un impulso de tráfico durante períodos cortos de tiempo.

El desafío principal es ajustar la combinación del tamaño del cubo y la velocidad de reabastecimiento de tokens.

Cubo de Fugas

El algoritmo del cubo de fugas es bastante similar al cubo de tokens. La única diferencia es que las solicitudes se procesan a una velocidad fija.

Se implementa con un enfoque FIFO. Cuando llega una solicitud, el sistema verifica si la cola está llena. Si no lo está, se agrega la solicitud a la cola, de lo contrario, se descarta.

Las solicitudes en la cola se procesan a una velocidad fija para evitar abrumar al servidor.

Casos de Uso de un Limitador de Velocidad

Aunque puede ser fácil pensar en un limitador de velocidad como una protección para tu sistema contra solicitudes externas, también puede ayudarte internamente.

Antes de finalizar esta publicación de introducción, analicemos algunos de los casos de uso prominentes de un limitador de velocidad, que incluyen casos de uso tanto externos como internos.

  • Prevenir ataques DDoS catastróficos— Esto se logra mediante la identificación de direcciones IP maliciosas, usuarios o tokens de solicitud que intentan abrumar el sistema. Las solicitudes se descartan según el algoritmo.
  • Manejar de manera elegante un aumento repentino de usuarios— No todo el tráfico es malicioso y a veces tu sitio web puede atraer un aumento de tráfico legítimo. Sin embargo, si no tienes la capacidad para manejar el aumento de tráfico, es mejor manejar las cosas de manera elegante en lugar de presentar a los usuarios una pantalla de error.
  • Precios escalonados— Este es un caso de uso interno donde es posible que desees ofrecer diferentes niveles de uso a usuarios que pertenecen a diferentes niveles. Este es un requisito típico para muchos servicios SaaS bajo demanda.
  • No abusar de un sistema de terceros— Este es otro caso de uso interno donde es posible que desees controlar la cantidad de llamadas a la API que estás realizando a una API de terceros costosa (como un modelo de aprendizaje profundo). Puedes usar la limitación de velocidad para restringir el número de llamadas.
  • Proteger un sistema desprotegido— A veces, es posible que queramos tratar con precaución un sistema desprotegido. Por ejemplo, si deseas eliminar un millón de registros de una base de datos, corres el riesgo de que la base de datos se caiga si realizas la operación de una vez. Puedes aprovechar un algoritmo de limitación de velocidad para distribuir las eliminaciones de manera uniforme.

Conclusion

La limitación de tasa es una herramienta importante para construir sistemas con un alto nivel de disponibilidad. En esta publicación, solo hemos cubierto una visión general del panorama de la limitación de tasa y por qué la necesitamos en primer lugar. Cada uno de los algoritmos mencionados en esta publicación tiene su propia fundamentación teórica y consideraciones prácticas.

Si tienes alguna pregunta o comentario, no dudes en mencionarlos en la sección de comentarios a continuación.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Trabajos que la IA no puede reemplazar

Introducción Ya seas un cibernauta o no, es probable que hayas escuchado el debate sobre los “empleos que la IA...

Inteligencia Artificial

¿Qué tan fácil es engañar a las herramientas de detección de inteligencia artificial?

Los detectores ignoran todas las pistas de contexto, por lo que no procesan la existencia de un autómata realista en ...

Inteligencia Artificial

5 Programas de Certificación en IA en línea - Explora e Inscríbete

Toma un curso de certificación de IA reconocido a nivel mundial y obtén un certificado para adquirir habilidades en I...