tag español attribute php laravel laravel-5 guzzle guzzle6

php - attribute - title html español



Solicitudes de boquillas de cola con límites (3)

Estoy trabajando en una aplicación Laravel, utilizando Guzzle 6. Una gran cantidad de funciones se basa en una API, para la cual he creado un contenedor.

Mi envoltorio es de una sola clase, que crea el cliente Guzzle en el __construct() , y tiene una variedad de funciones públicas que devuelven respuestas de las solicitudes de Guzzle.

La API que estoy usando tiene un límite de 40 solicitudes cada 10 segundos. Estoy guardando cosas en caché, por lo que sería muy raro alcanzar este límite, ¡pero me gustaría saber que mi aplicación no se moriría si lo hiciera!

Algunas notas sobre mi aplicación:

  • Las llamadas API solo se realizan si no se ha realizado la misma llamada en las últimas 6 horas. Si es así, la llamada nunca se realiza y la respuesta se sirve directamente desde mi caché de redis.
  • En la mayoría de los casos, las llamadas a la API se realizan a través de acciones del usuario. La aplicación nunca se acercaría a alcanzar estos límites por sí misma.
  • En la mayoría de los casos, ya tengo los datos necesarios para mostrar las páginas solicitadas a los usuarios. Se puede hacer una llamada a la API en segundo plano para ver si es necesario actualizar algo en mi final, pero si ya tengo los datos y la solicitud de la API falló, esto no haría que la página fuera inútil.
  • La aplicación está en vivo, https://likethis.tv si desea ver. Estoy usando la API TMDb .

Entonces, mi pregunta es, ¿cómo debo asegurarme de no alcanzar este límite? Algunas ideas mías son las siguientes:

  • Use el sistema de colas Laravel para colocar las solicitudes de Guzzle en una cola, y solo procéselas si aún nos quedan solicitudes. Si no, espera hasta que el tiempo de reutilización de 10 segundos haya pasado ...
  • Utilice un HandlerStack para Guzzle directamente. No estoy seguro de si esto es posible, pero he usado el HandlerStack para almacenar respuestas en caché anteriormente.

Estoy tratando de no provocar respuestas demasiado evaluadas, pero estoy seguro de que probablemente haya una forma mejor y / o más fácil que la anterior, o si son buenas ideas, cualquier sugerencia o recomendación sería genial.

Gracias por adelantado.


No hay suficiente información para profundizar en esto, pero para comenzar, las buenas API generalmente devuelven un código de respuesta 429 cuando se excede su límite de aceleración.

Podría usar $res->getStatusCode() de guzzle para verificar esto y enviar un mensaje al usuario si está realizando demasiadas solicitudes demasiado rápido.

¿Puedes dar más información sobre lo que está haciendo tu aplicación? ¿Está haciendo solicitudes en un bucle foreach? ¿La vista depende de los datos de esta API?


Personalmente creo que Guzzle no debería manejar este caso, pero si quiere que Guzzle lo maneje, escribiría un Middleware que verifique la respuesta y si devuelve un error de límite de tasa (por ejemplo, el código de estado 429). Luego puede emitir un error personalizado o esperar hasta que finalice el límite de velocidad e intentarlo de nuevo. Sin embargo, esto podría terminar en un largo tiempo de respuesta (ya que espera el límite de frecuencia).

No creo que la cola de Laravel sea mejor, ya que la respuesta estaría disponible de forma asíncrona y tendría que sondear su base de datos o su caché, donde sea que almacene los resultados. (Por supuesto, puede funcionar si no necesita que los resultados estén disponibles de inmediato)

Si este servicio de terceros está conectado directamente a una interfaz orientada al usuario, probablemente aplicaría el mismo límite de velocidad (en el código de su aplicación) y devolvería un mensaje de error al usuario en lugar de esperar y resolver el problema.


También estoy trabajando en el mismo problema, preferí una arquitectura basada en devolución de llamada donde mi clase de Client controla el flujo de solicitudes. Actualmente estoy haciendo dormir y comprobar algoritmo. Me funciona porque tengo 3 segundos de tiempo de enfriamiento.

Uso Cache para mantener el recuento de solicitudes disparadas.

while(($count = Cache::get($this->getCacheKey(),0)) >= 40){ // Max request sleep(1); } Cache::set($this->getCacheKey(), ++$count); // fire request function getCacheKey(){ return floor(time()/10); // Cool down time }

Hacer cola parece ser una mejor opción, y eventualmente me moveré a eso. Hay algunas cosas que debe tener en cuenta antes de poner la cola entre ellas.

  1. Arquitectura basada en devolución de llamada, ya que es posible que deba guardar un estado de código serializado en la cola. El diseño basado en devolución de llamada le dará control total a la Clase Client . No tendrá que preocuparse por la aceleración en su código.
  2. La serialización podría ser complicada, intente __sleep y __wakeup .
  3. También es posible que desee priorizar algunas llamadas, puede asignar una cuota de clientes para dichas llamadas.