ruby-on-rails - scotch - ruby server
¿La mejor práctica para los usuarios que limitan la velocidad de una API REST? (3)
Estoy preparando 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 y poder rechazar temporalmente las solicitudes cuando la caja está por encima de la capacidad o si hay algún tipo de escenario de slashdotted.
También me gustaría poder desactivar el servicio temporalmente (mientras doy a los clientes resultados que indican que el servicio principal está desconectado un poco) 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.
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, análisis, etc. para las API. Funciona con un complemento (ver aquí el plugin api de ruby ) 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.
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
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 puede limitar, es decir, 50 req / minuto por cada IP, y obtener 503 páginas, que puedes personalizar.
Con respecto al descenso temporal esperado, 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 independiente del servidor de aplicaciones en diferentes puertos UNIX socket / IP y tener balanceador (nginx / lighty / haproxy) también use esa nueva instancia. 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 sólo para equilibradores. Puede equilibrar de manera extremadamente eficiente las solicitudes a los servidores de aplicaciones en su granja.
Para un servicio bastante grande terminas con algo como:
- api.domain que se resuelve en balanceadores N de round-robin
- cada equilibrador envía solicitudes a los servidores web M para servidores de aplicaciones P y estáticos para contenido dinámico. Ah, bueno, su API REST no tiene archivos estáticos, ¿o sí?
Para un servicio bastante pequeño (por debajo de 2K rps), todo el equilibrio se realiza dentro de uno-dos servidores web.