2009-03-05 10 views
30

Sto assemblando un'API REST e siccome non sono sicuro di come verrà ridimensionata o quale sarà la domanda, mi piacerebbe essere in grado di valutarne gli usi limitati e di essere in grado di rifiutare temporaneamente richiede quando la scatola ha una capacità eccessiva o se c'è qualche tipo di scenario con slash.Le migliori pratiche per la limitazione della velocità degli utenti di un'API REST?

Vorrei anche essere in grado di abbassare temporaneamente il servizio temporaneamente (dando ai client risultati che indicano che il servizio principale è offline per un po ') quando/se ho bisogno di scalare il servizio aggiungendo più capacità.

Esistono buone pratiche per questo genere di cose? L'implementazione è Rails con mysql.

risposta

17

Tutto ciò è fatto con il webserver esterno, che ascolta il mondo (io consiglio nginx o lighttpd).

Per quanto riguarda i limiti di velocità, nginx è in grado di limitare, vale a dire 50 req/minuto per ogni IP, in tutto ottenere 503 pagine, che è possibile personalizzare.

Per quanto riguarda le temporanee previste, nel mondo delle rotaie ciò avviene tramite la pagina di manutenzione speciale.html. C'è un qualche tipo di automazione che crea o simbolizza quel file quando i server delle app delle rotaie si abbassano. Ti consiglio di fare affidamento non sulla presenza di file, ma sulla disponibilità effettiva del server delle app.

Ma in realtà sei in grado di avviare/interrompere i servizi senza perdere alcuna connessione. Cioè è possibile eseguire un'istanza separata del server delle app su diversi socket UNIX/IP e disporre di un sistema di bilanciamento (nginx/lighty/haproxy) che utilizza anche questa nuova istanza. Quindi chiudi la vecchia istanza e tutti i client vengono serviti con solo uno nuovo. Nessuna connessione persa. Ovviamente questo scenario non è sempre possibile, dipende dal tipo di modifica introdotta nella nuova versione.

haproxy è una soluzione di sola bilanciamento. Può bilanciare in modo estremamente efficiente le richieste ai server delle app della tua farm.

Per abbastanza grande servizio si finisce-up con qualcosa di simile:

  • api.domain risolvere al round robin N bilanciatori
  • ogni bilanciamento deleghe richieste al server web M per i server di applicazioni statiche e dinamiche per P soddisfare. Oh bene, la tua API REST non ha file statici, vero?

Per servizi di dimensioni ridotte (meno di 2 K rps) tutto il bilanciamento viene eseguito all'interno di uno-due server web.

2

Suggerirei di implementare i limiti di velocità al di fuori della vostra applicazione poiché altrimenti il ​​traffico elevato avrà ancora l'effetto di uccidere la vostra app. Una buona soluzione è implementarla come parte del tuo proxy Apache, con qualcosa come mod_evasive

+1

Non esce Apache dal terreno con carico elevato? frankodwyer ha sicuramente bisogno di una rete asincrona per gestire molte connessioni simultanee e mpm_event non è ancora stabile alla produzione. Ovviamente l'apache potrebbe essere messo su box separati ... è lì il punto di comprarli solo per restare con l'apache? – temoto

+1

Suppongo che dipenda dal probabile volume di richieste e dal costo di ciascuna richiesta all'applicazione.Secondo la mia esperienza, Apache può facilmente gestire ordini di grandezza più richieste rispetto all'app di back-end che rende una multa proxy condivisa. –

5

Buone risposte già - se non si desidera implementare il limitatore autonomamente, esistono anche soluzioni come 3scale (http://www.3scale.net) che limitano la velocità, l'analisi ecc. Per le API. Funziona usando un plugin (vedi qui per il ruby api plugin) che si aggancia all'architettura 3scale. Puoi anche usarlo tramite vernice e avere la vernice agire come un proxy che limita la velocità.

Problemi correlati