2009-03-05 20 views
30

Estoy armando una API REST y como no estoy seguro de cómo se escalará o cuál será su demanda, me gustaría poder calificar los usos límite de la misma así como también poder rechazarla temporalmente solicita cuando la caja está sobre capacidad o si hay algún tipo de escenario de slashdotted.¿La mejor práctica para los usuarios que limitan la velocidad de una API REST?

También me gustaría poder bajar el servicio temporalmente (al tiempo que proporciono a los clientes resultados que indican que el servicio principal está fuera de línea por un tiempo) cuando/si necesito escalar el servicio agregando más capacidad.

¿Existen mejores prácticas para este tipo de cosas? La implementación es Rails con mysql.

Respuesta

17

Todo esto se hace con el servidor web externo, que escucha al mundo (recomiendo nginx o lighttpd).

En cuanto a los límites de velocidad, nginx es capaz de limitar, es decir, 50 req/minuto por cada IP, en todo obtener 503 páginas, que puede personalizar.

En cuanto a la baja temporal esperada, en el mundo de los rieles esto se hace a través de la página especial maintainance.html. Existe algún tipo de automatización que crea o enlaza ese archivo simbólicamente cuando los servidores de la aplicación Rails bajan. Recomiendo confiar no en la presencia de archivos, sino en la disponibilidad real del servidor de aplicaciones.

Pero realmente puede iniciar/detener servicios sin perder ninguna conexión. Es decir. puede ejecutar una instancia separada del servidor de aplicaciones en diferentes puertos UNIX socket/IP y tener balancer (nginx/lighty/haproxy) usar esa nueva instancia también. Luego apaga la instancia anterior y todos los clientes reciben solo una nueva. Sin conexión perdida. Por supuesto, este escenario no siempre es posible, depende del tipo de cambio que introdujo en la nueva versión.

haproxy es una solución solo equilibradora. Puede equilibrar de manera extremadamente eficiente las solicitudes a los servidores de aplicaciones en su granja.

Por bastante grande servicio que termina arriba con algo como:

  • api.domain resolver a round-robin N balanceadores
  • cada uno de equilibrado proxies solicitudes a servidores web M para servidores de aplicaciones estáticas y dinámicas para P contenido. Ah, bueno, su API REST no tiene archivos estáticos, ¿o sí?

Para un servicio bastante pequeño (menos de 2K rps), todo el equilibrio se realiza dentro de uno-dos servidores web.

2

Recomiendo implementar los límites de velocidad fuera de su aplicación ya que de lo contrario el alto tráfico seguirá teniendo el efecto de matar su aplicación. Una buena solución es implementarlo como parte de su proxy apache, con algo como mod_evasive

+1

¿Apache no está fuera de la tierra de alta carga? frankodwyer definitivamente necesita una red asíncrona para manejar muchas conexiones concurrentes y mpm_event aún no es estable en producción. Por supuesto, apache podría colocarse en cajas separadas ... ¿Hay algún punto para comprarlas solo para quedarse con apache? – temoto

+1

Supongo que depende del volumen probable de solicitudes y el costo de cada solicitud a la aplicación.En mi experiencia, apache puede manejar órdenes de magnitud de más solicitudes que la aplicación de back-end, lo que hace que un proxy coubicado esté bien. –

5

Buenas respuestas ya: si no desea implementar el limitador usted mismo, también hay soluciones como 3scale (http://www.3scale.net) que limita la velocidad, analíticas, etc. para las API. Funciona con un complemento (ver aquí para ruby api plugin) que se engancha en la arquitectura de 3 escalas. También puede usarlo a través de barniz y hacer que el barniz actúe como un proxy limitador de velocidad.

Cuestiones relacionadas