Ridimensionamento delle connessioni client websocket (non server) su più server

2

Ho scritto un bot Slack che deve connettersi ai team Slack tramite connessioni websocket. Poiché il bot potrebbe essere utilizzato da migliaia di team, alla fine dovrò distribuire i team su più server. I nuovi team vengono aggiunti tramite un server HTTP che gestisce l'autenticazione OAuth iniziale.

Sto cercando soluzioni che mi consentano di ottenere quanto segue:

  • Quando un server si arresta o si riavvia, tutti i team a cui è stato assegnato devono essere nuovamente assegnati ai server rimanenti. Va bene se la connessione al team Slack si interrompe temporaneamente finché il team viene prelevato rapidamente da un server.

  • Quando una squadra viene aggiunta, viene assegnata al server meno "occupato". Occupato potrebbe essere semplicemente definito dalla quantità di team che gestisce attualmente.

  • Mi piacerebbe fare tutto questo con un codice personalizzato minimo per scrivere.

Finora, ho considerato le seguenti soluzioni:

1) Coda di lavoro con RabbitMQ. I server Bot competono per ricevere team. Questa è una soluzione OK anche se ho bisogno di un modo affidabile per rimettere i team in coda quando un server si ferma.

2) Scrivi un servizio personalizzato di "orchestrazione". Il servizio di orchestrazione riceverà i team dal server http e li invierà a un cluster di server. Dovrebbe tenere traccia di quando i server vanno giù e quali team devono essere riassegnati. Non sono sicuro di come scrivere in modo affidabile un servizio del genere e questo diventerebbe un singolo punto di errore.

3) I tuoi suggerimenti!

    
posta Olivier Lalonde 13.02.2016 - 08:19
fonte

1 risposta

1

Fondamentalmente, stai cercando consigli su come ottenere il bilanciamento del carico. Anche con le limitazioni che hai offerto, questo è un argomento abbastanza ampio.

Una possibile soluzione:

Partendo dal presupposto che tu abbia qualche mezzo per qualsiasi cliente arbitrario per ottenere un elenco di server attualmente attivi, potresti usare qualche variazione su Hashing coerente o Rendezvous Hashing .

Come esempio semplificato, si mappano ciascun server a numerosi valori del bucket casuale compresi tra 0 e 1. Per un determinato client, si hash una sorta di id client (ad esempio, l'indirizzo IP del client) a un numero, quindi inviarlo a il server con un bucket più vicino al server selezionato [1] .

Ci sono molti vantaggi in questo approccio:

  • Oltre a mantenere l'elenco dei server, tutta questa logica può essere fatto lato client.
  • La logica è incredibilmente semplice; implementando questo la funzionalità dovrebbe richiedere solo 10-20 righe di codice.
  • Aggiunta o la rimozione dei server viene gestita in modo pulito. Quando viene aggiunto un server, la maggior parte dei client non cambierà server. Quando un server viene perso, verranno rimappati solo i client di quel server.

Il lato negativo di questo approccio è che è casuale. Esiste il rischio che il carico non venga distribuito uniformemente, specialmente se il numero di client è basso.

[1] Questo calcolo si conclude (quindi perché la maggior parte delle discussioni parla di angoli o cerchi), ma l'impatto di ignorare questo è piuttosto piccolo. La soluzione più semplice è aggiungere un extra 1+Min(bucket_value) bucket. In sostanza, lo 0,01 deve essere considerato più vicino a 0,99 che a 0,5 per evitare di pesare i valori di secchio più alto e più basso meno irregolarmente.

    
risposta data 13.02.2016 - 10:17
fonte