Come gestire una grande quantità di client autenticati

6

Al momento ho creato un server multithread in c ++ per windows, in cui ogni client connesso ottiene un thread che rimane in esecuzione fino a quando il socket del client non viene chiuso.
Quando un client si connette, può eseguire comandi (recupera motd, ottiene la versione corrente del client) o può accedere per ottenere l'accesso ad altri comandi (recuperare informazioni utente, scaricare file, ecc.).

Finora questo approccio di base ha funzionato bene, ma ho notato che c'è stato un numero crescente di clienti che utilizzano il mio servizio e sto iniziando a preoccuparmi di quanto sia efficiente questo approccio. Ho letto online che un processo in Windows può gestire solo da 1500-2000 thread, e penso che potrei presto raggiungere quella quantità di utenti simultanei, e penso che sia ora che cambi il mio progetto.

Quale sarebbe il modo migliore per gestire questo numero di utenti?

    
posta hopeless_nerd 21.09.2014 - 20:09
fonte

2 risposte

2

Il limite di thread 2000 per processo è il risultato della dimensione massima dello stack predefinita per un processo di Windows . Come afferma l'articolo collegato, puoi aumentare il limite disponendo di un thread dedicato per client ma non della soluzione più scalabile.

Usa invece le porte di completamento I / O asincrone per gestire il tuo I / O. Invece di bloccare il thread, il codice attende su un gruppo di socket aperti e viene avvisato quando i dati vengono ricevuti da uno di essi. Trasmetti i dati come "oggetto di lavoro" a un pool di thread , un gruppo di thread gestiti da Windows. Windows fornisce anche BindIoCompletionCallback per automatizzarlo per te . Questo dovrebbe fare un uso migliore delle risorse che hai, permettendoti di scalare ulteriormente.

L'altra opzione è quella di dividere gli utenti in gruppi separati, ciascuno su un altro server. Se gli utenti non hanno bisogno di comunicare tra loro e i dati (come il motd oi file citati sopra) sono memorizzati centralmente. Puoi aggiungere un nuovo server ogni poche migliaia di utenti.

Allo stesso modo, se gli utenti non devono essere legati a server specifici, è possibile allocare gli utenti ai server in modo dinamico in un cluster, il che significa che un server guasto viene gestito in modo trasparente. Non dici dove è ospitato il tuo server ma il bilanciamento del carico è poco costoso in questi giorni, disponibile come parte di AWS e Azure .

    
risposta data 26.10.2014 - 01:33
fonte
0

Non parli di quanti utenti pensi che questa cosa possa scalare, e se quel numero è illimitato o sconosciuto (ma in crescita) questo non scalerà molto bene nel lungo periodo.

Un modo per farlo è quello di mantenere un pool di ID utente autenticati con una sorta di valore di scadenza di 15 minuti o qualcosa del genere. Se un utente fa una richiesta, la tua logica dovrebbe verificare se sono loggati e entro il limite di scadenza (resetta anche questo limite) se sono fuori dal limite di scadenza, chiedi loro di accedere nuovamente.

Sembra che anche tu correrai dei problemi se lo mantieni in questo modo ma espandi il tuo server orizzontalmente e fai il load balancing. In questo caso, le condizioni di gara possono o non possono influire su di te.

Solo alcuni pensieri ingenui, ma sembra che l'obiettivo sarebbe quello di spingere più utenti utilizzando un singolo thread e mantenere un rapporto tra n utenti e 1 thread in base al carico e al blocco.

    
risposta data 25.09.2014 - 22:16
fonte

Leggi altre domande sui tag