Domanda

che sto passando un po 'di ri-pensare a giochi multiplayer su larga scala in età di applicazioni di Facebook e il cloud computing.

Supponiamo che io dovessi costruire qualcosa in cima protocolli aperti esistenti, e voglio servire 1.000.000 giocatori simultanei, solo per la portata del problema.

Si supponga che ogni giocatore ha una coda di messaggi in entrata (per la chat e quant'altro), e, in media ancora una coda di messaggi in entrata (corporazioni, le zone, le istanze, asta, ...) così abbiamo 2.000.000 di code. Un giocatore ascolterà 1-10 code alla volta. Ogni coda avrà, in media, forse 1 messaggio al secondo, ma alcune code avrà tasso molto più alto e il più alto numero di ascoltatori (per esempio, una coda "Posizione entità" per un'istanza di livello). Supponiamo che non più di 100 millisecondi di latenza del sistema di accodamento, che è OK per moderatamente orientato all'azione giochi (ma non giochi come Quake o Unreal Tournament).

Da altri sistemi, io so che serve 10.000 utenti su un singolo 1U o scatola lama è una ragionevole aspettativa (supponendo che non c'è niente altro costoso in corso, come la simulazione fisica o roba del genere).

Così, con un sistema di cluster traversa, dove i client si connettono al gateway di connessione, che a loro volta si collegano al server coda di messaggi, otterremmo 10.000 utenti al gateway con 100 macchine di gateway, e 20.000 code di messaggi per server coda con 100 coda macchinari. Anche in questo caso, solo per scoping generale. Il numero di connessioni su ogni macchina MQ sarebbe molto piccola: circa 100, per parlare a ciascuno dei gateway. Il numero di connessioni sui gateway sarebbe alot più alto: 10.100 per i clienti + collegamenti a tutti i server di coda. (In cima a questo, aggiungere alcune connessioni per i server di gioco di simulazione del mondo o roba del genere, ma io sto cercando di mantenere quella separata per ora)

Se io non volevo costruire questo da zero, avrei dovuto usare un po 'di messaggistica e / o le infrastrutture in coda che esiste. I due protocolli aperti che posso trovare sono AMQP e XMPP. La destinazione d'uso di XMPP è un po 'più simile a ciò che questo sistema di gioco avrebbe bisogno, ma l'overhead è abbastanza evidente (XML, più i dati di presenza dettagliati, oltre a vari altri canali che devono essere costruiti in alto). Il modello di dati effettivo di AMQP è più vicino a quello che ho descritto sopra, ma tutti gli utenti sembrano essere grandi, impresa-tipo corporazioni, e i carichi di lavoro sembrano essere il flusso di lavoro correlato, non in tempo reale aggiornamento del gioco correlate.

Qualcuno ha alcuna esperienza di giorno con queste tecnologie, o implementazioni della stessa, che è possibile condividere?

È stato utile?

Soluzione

@MSalters

Re 'coda di messaggi':

operazione di default di RabbitMQ è esattamente ciò che si descrive: PubSub transitoria. Ma con il protocollo TCP invece di UDP.

Se si desidera eventuale consegna garantita e altre caratteristiche di persistenza e di recupero, allora si può avere anche questo - è un'opzione. Questo è il punto di RabbitMQ e AMQP -. Si può avere un sacco di comportamenti con un solo sistema di recapito dei messaggi

Il modello che si descrive è il comportamento di default, che è transitorio, "spara e dimentica", e routing dei messaggi ovunque i destinatari sono. Le persone usano RabbitMQ fare rilevamento multicast su EC2 solo per questo motivo. È possibile ottenere di tipo UDP comportamenti oltre unicast PubSub TCP. Ordinato, eh?

Re UDP:

Non sono sicuro se UDP sarebbe utile qui. Se si spegne Nagling poi RabbitMQ singolo messaggio di latenza andata e ritorno (client-broker-cliente) è stata misurata a 250-300 microsecondi. Vedi qui per un confronto con una latenza di Windows (che era un po 'più alto) http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

Non riesco a pensare a molti giochi multiplayer che hanno bisogno di una latenza di andata e ritorno inferiori a 300 microsecondi. Si potrebbe ottenere sotto 300US con il protocollo TCP. TCP finestre è più costosi di quelli UDP crudo, ma se si utilizza UDP per andare più veloce, e aggiungere una perdita di recupero personalizzati o manager Nseq / ACK / rispedizione quindi che possono rallentare di nuovo. Tutto dipende dal vostro caso d'uso. Se davvero davvero davvero bisogno di usare UDP e ACK pigri e così via, allora si potrebbe eliminare fuori TCP di RabbitMQ e probabilmente tirare fuori.

Spero che questo aiuta a chiarire il motivo per cui ho raccomandato RabbitMQ per caso d'uso di Jon.

Altri suggerimenti

Sto costruendo un sistema così ora, in realtà.

Ho fatto una discreta quantità di valutazione di diversi mq, tra cui RabbitMQ, Qpid e ZeroMQ. La latenza e la velocità di qualsiasi di questi sono più che adeguata per questo tipo di applicazione. Ciò che non è buona, tuttavia, è ora di creazione della coda in mezzo a mezzo milione di code o più. Qpid in particolare degrada abbastanza gravemente dopo qualche migliaio di code. Per aggirare questo problema, in genere si devono creare i propri meccanismi di routing (più piccolo numero di code totali, e consumatori su queste code sono sempre i messaggi che non hanno interesse a).

Il mio sistema attuale sarà probabilmente usare ZeroMQ, ma in modo piuttosto limitato, all'interno il cluster. Collegamenti da clienti sono trattati con una sim personalizzato. demone che ho costruito utilizzando libev ed è interamente a thread singolo (e sta mostrando molto buona scalabilità - che dovrebbe essere in grado di gestire 50.000 connessioni su una scatola senza problemi -. il nostro sim barrare tasso è piuttosto basso, però, e non ci sono non fisica).

XML (e quindi XMPP) è molto non adatto a questo, come avrete PEG l'XML di elaborazione della CPU a lungo prima di essere vincolati in I / O, che non è quello che si desidera. Stiamo utilizzando Google Protocol Buffer, in questo momento, e quelli sembrano ben si adatta alle nostre esigenze particolari. Stiamo anche utilizzando il protocollo TCP per le connessioni client. Ho avuto esperienza utilizzando sia UDP e TCP per questo in passato, e come sottolineato da altri, UDP ha qualche vantaggio, ma è un po 'più difficile da lavorare.

Speriamo che quando siamo un po 'più vicino al lancio, sarò in grado di condividere ulteriori dettagli.

Jon, questo suona come un caso d'uso ideale per AMQP e RabbitMQ.

Non sono sicuro che il motivo per cui si dice che gli utenti AMQP sono tutte grandi aziende enterprise di tipo. Più della metà dei nostri clienti sono nello spazio di 'web' che vanno dalla enorme per le aziende molto piccole. Un sacco di giochi, sistemi di scommesse, sistemi di chat, sistemi di tipo twittery e infras di cloud computing sono stati costruiti fuori RabbitMQ. Ci sono anche applicazioni di telefonia mobile. I flussi di lavoro sono solo uno dei tanti casi d'uso.

Cerchiamo di tenere traccia di ciò che sta accadendo qui:

http://www.rabbitmq.com/how.html (assicuratevi scegliere attraverso gli elenchi dei casi d'uso su del.icio.us troppo!)

Si prega di dare un'occhiata. Siamo qui per aiutare. Non esitate a contattarci via email a info@rabbitmq.com o mi ha colpito su twitter (@monadic).

FWIW, per i casi in cui i risultati intermedi non sono importanti (come informazioni di posizionamento) Qpid ha una "coda all'ultimo valore" in grado di fornire solo il valore più recente ad un abbonato.

La mia esperienza è stata con un'alternativa non aperto, BizTalk. La lezione più dolorosa che abbiamo imparato è che questi sistemi complessi non sono veloci. E come si imparano dai requisiti hardware, che si traduce direttamente in costi significativi.

Per questo motivo, non hanno nemmeno andare vicino XML per le interfacce di base. Il cluster di server verrà parsing 2 milioni di messaggi al secondo. Che potrebbe facilmente essere 2-20 GB / sec di XML! Tuttavia, la maggior parte dei messaggi saranno per un paio di code, mentre la maggior parte le code sono infatti a basso traffico.

Quindi, progettare l'architettura in modo che sia facile per iniziare con i server di coda COTS e quindi spostare ogni coda (tipo) a un server di coda personalizzato quando viene identificato un collo di bottiglia.

Inoltre, per ragioni analoghe, non dare per scontato che un'architettura di coda di messaggi è il migliore per tutte le esigenze di comminication l'applicazione dispone. Prendete il vostro "posizione entità in un'istanza" esempio. Questo è un classico caso in cui si non vogliono garantita la consegna dei messaggi. La ragione per cui è necessario condividere questa informazione è perché cambia tutto il tempo. Quindi, se un messaggio è perso, non si vuole spendere il tempo di recupero di esso. Devi inviare solo il vecchio locatiom dell'entità interessata. Invece, che ci si vuole inviare il corrente posizione di tale entità. Tecnologia-saggio questo significa che si desidera UDP, non TCP e un meccanismo di perdita di recupero personalizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top