Come limitare la quantità di richieste al minuto a un sistema esterno in un ambiente di micro servizi?

0

Ho qualche problema a pensare a una soluzione per controllare la quantità di richieste al minuto verso un sistema esterno in un ambiente di micro servizi su Kubernetes.

Lo scenario

Questo sistema esterno è un'applicazione di e-mail marketing (denominata Responsys) che consente solo una certa quantità di richieste al minuto per ogni accesso. Alcuni tipi di e-mail usano 2 richieste e alcuni tipi di e-mail usano solo una richiesta *.

In realtà, ogni sistema che deve inviare una e-mail invia un messaggio a una coda RabbitMQ e uno dei nostri micro-servizi è responsabile di consumare questo messaggio, leggere le informazioni e comunicare con Responsys che obbedisce a 40 richieste per limitazione dei minuti .

La soluzione attuale

L'attuale versione funzionante di questa integrazione ottiene 20 messaggi alla volta dalla coda utilizzando un semplice processo pianificato. Perché 20? Nel peggiore dei casi, queste 20 e-mail consumeranno 2 richieste. Ogni e-mail viene elaborata in modo asincrono, quindi queste 20 e-mail comunicheranno con Responsys allo stesso tempo. Le e-mail che non possono essere elaborate (Responsys può generare un errore), salviamo su una tabella di database per essere analizzate in seguito.

Funziona davvero bene, anche se non è ottimizzato perché alcuni tipi di e-mail usano solo una richiesta. Ma c'è un problema su quella soluzione che può danneggiare il nostro limite di richieste.

Il problema

Kubernetes può capire a un certo punto, usando i suoi algoritmi delle prestazioni, che è necessaria un'altra istanza di micro servizio (che si integra con Responsys). Se ciò accade, ciò interromperà la nostra limitazione delle richieste, poiché ci saranno due (o più) istanze che leggono i messaggi dalla coda e provano l'invio di e-mail tramite Responsys, superando le 40 richieste al minuto.

Mi è venuta l'idea di configurare il servizio micro su Kubernetes per non creare alcuna replica di questo servizio micro, garantendo solo un'istanza, perché questo micro servizio è piuttosto semplice e specializzato. Non so come farlo esattamente, ma sembra molto semplice leggere la documentazione di Kubernetes, ma ai miei college non piace l'idea, perché potrebbe esistere qualche strano scenario di errore in cui potrebbero esistere due istanze.

Quindi, stiamo cercando di pensare a una soluzione oltre all'istanza del servizio micro, utilizzando una sorta di "sistema ticket" letto da una cache (Redis) condivisa da un numero qualsiasi di istanze di micro-servizi. Questa sembra una soluzione pesante per un problema semplice, quindi mi piacerebbe avere qualche aiuto per trovare un'altra alternativa per questo.

* Ho semplificato il problema, perché la limitazione delle richieste per minuto è diversa da due diversi endpoint. Uno di questi consente 200 richieste al minuto e altre 40 al minuto. Limiterò il numero di richieste al minuto utilizzando il limite dall'endpoint più restrittivo.

    
posta Dherik 10.07.2018 - 23:33
fonte

2 risposte

5

Penso che tutto ciò riguardi la resilienza:)

Cosa succede se viene raggiunta la limitazione della richiesta? I "responsys" faranno semplicemente un errore o diranno davvero al microservice che chiama il limite? Il microservizio si ripristinerà correttamente?

Non dovrebbe importare quante istanze del tuo microservice chiamante hai (questo è il punto di utilizzo del ridimensionamento automatico reale lì), a patto che possano recuperare quando si colpisce la velocità limite . Se ad es. la chiamata sarebbe una richiesta http e responsys risponde con un codice HTTP corretto (iirc 429). Il tuo microservizio potrebbe semplicemente "riprovare più tardi". Se la implementi, puoi ignorare completamente il limite di velocità del callee nel tuo codice microservizio, ma ciò che non dovrebbe essere la sua preoccupazione comunque. Se un giorno o l'altro in futuro togli o aumenti il limite di velocità sul callee, non avrai nemmeno bisogno di toccare nuovamente il tuo microservizio:)

    
risposta data 11.07.2018 - 13:34
fonte
0

Finisco per spostare la mia routine di pianificazione di un minuto dal servizio micro al Cronub di Kubernetes. Pertanto, ogni volta che viene eseguito il processo, viene chiamato solo un POD (micro service instance) e non è necessario preoccuparsi della concorrenza tra di essi. Un college ha suggerito qualcosa di simile, ma utilizzando ShedLock invece di K8S CronJob.

Non è una soluzione perfetta, ma ha funzionato ..

    
risposta data 18.07.2018 - 16:29
fonte

Leggi altre domande sui tag