2012-01-08 43 views
45

¿Cuál es la mejor manera de limitar las solicitudes de una API? Básicamente, queremos limitar a los usuarios a 360 solicitudes API por hora (una solicitud cada 10 segundos). Lo que viene a la mente es el seguimiento de todas las solicitudes de API y almacenamiento:Cómo calificar-limitar una API

ip-address   hourly-requests 
    1.2.3.4    77 
    2.3.4.5    34 
    3.4.5.6    124 

Si las peticiones de direcciones IP es mayor que 360, devuelva una cabecera con:

429 - Too Many Requests 

Luego deshacer el contador por hora-solicitudes cada hora. Esto parece ser un método muy ineficiente, ya que tenemos que hacer una consulta de MySQL en cada solicitud de API para incrementar el contador. Además, necesitaríamos una tarea cron para restablecer todos los contadores cada hora.

¿Existe una solución más elegante/eficiente?

+0

Para un enfoque más elástico es posible que desee echar un vistazo a [Token Bucket Algorithm] (https://en.wikipedia.org/wiki/Token_bucket). Los contadores deben mantenerse en alguna memoria de tienda, para el rendimiento. – botchniaque

Respuesta

2

Actualmente estoy investigando este problema. Mi plan actual (¡Observe que esto es con una pila LAMP!) Es implementar esto usando las funciones de caché de APC. Cuando se recibe una solicitud, verifico si esa IP está almacenada en el caché de APC. Si es así, verifique si es mayor que 'X', donde 'X' es el máximo de solicitudes por unidad de tiempo. Si no es así, cree la entrada de caché para esa IP.

Este sistema significa que no se requiere acceso a la base de datos para comprobar la limitación de velocidad, y no depende de nada como un servidor MongoDB o Redis. Asume que estás usando PHP con APC; si no lo eres, entonces Memcached podría funcionar en su lugar.

10

Definitivamente no recomendaría hacer esto con MySQL - el problema no es tanto lecturas o la ineficiencia en el algoritmo que está resaltando allí - sino que escribe. A medida que aumentan los volúmenes, comenzarás a escribir en varios segundos. Usamos REDIS como almacenamiento como otro póster ya mencionado, tiene funciones de incremento/decrecimiento atómico que son exactamente lo que necesita + es extremadamente rápido (en la memoria) - solo tiene que gestionar la fragmentación en volúmenes ultra altos (pero que el ultra alto es muchos órdenes de magnitud sobre MySQL). Otra opción si no está familiarizado con REDIS lo está haciendo en Memcached, pero no es tan agradable a nivel de operaciones.

Otra opción es usar algo como 3scale (http://www.3scale.net) que efectivamente hace todo esto por ti + otras cosas (análisis, gestión de claves, documentos de desarrollador, etc.). Existen complementos de código para una gran cantidad de idiomas (https://support.3scale.net/libraries) y estos se conectan a la infraestructura. También puede usar Varnish Libmod (https://github.com/3scale/libvmod-3scale/) y conectarlo a un caché de Varnish en frente de la API.

4

Por una cantidad ideal de rendimiento, puede ejecutar un marco de tela ligera con funciones para la gestión de registros en una in-memory database para la monitorización y el registro de los datos de tráfico, ya sea basado en IP o Usuario o Servicio llamado por el usuario. La opción más importante es el almacenamiento de datos que desea emplear.

mejores y más utilizados opciones gratuitas son:

redis.io avanzada almacén de claves-valor

ehcache basados ​​en estándares de caché, desarrollado activamente, mantenido y apoyado como un proyecto de código abierto profesional mediante la terracota

hazelcast una cuadrícula de datos en memoria de fuente abierta para una ejecución más rápida y una escalabilidad elástica perfecta

VoltDB una opción en memoria base de datos de operaciones

8

Pruebe nginx. La limitación de velocidad se puede realizar fácilmente escribiendo simples cambios en el archivo de configuración. Por otra parte, nginx es rápido.