2012-04-11 14 views
6

Sto costruendo un sistema distribuito che consiste potenzialmente di milioni di client che hanno tutti bisogno di mantenere una connessione aperta (preferibilmente HTTP) per attendere un comando dal server (che sta girando da qualche altra parte) . Il carico di messaggi/commmandi non sarà molto alto, forse un messaggio/sec/1000 client, il che significa che sarebbe 1000 msg/sec a 1 milione di client. => si tratta fondamentalmente delle connessioni simultanee.server push per milioni di connessioni simultanee

Anche i requisiti sono semplici. Messaggi di sola andata (server-> client), solo 1 client per "canale".

Sono abbastanza aperto in termini di tecnologia (xmpp/websockets/comet/...). Sto usando Google App Engine come server, ma i loro "canali" non funzionano per me sfortunatamente (quote troppo basse e nessun client Java). XMPP era un'opzione ma è piuttosto costoso. Finora stavo usando URL Fetch & pubnub, ma hanno appena iniziato a pagare per le connessioni (grande tempo).

Quindi:

  1. Qualcuno sa di un servizio là fuori che può fare questo per me in un modo conveniente? La maggior parte ho trovato limitato o pesantemente addebito per le connessioni.

  2. Qualche esperienza con l'implementazione di un server di questo tipo? L'ho già fatto e funziona abbastanza bene (basato su Tomcat & NIO) ma non ho ancora avuto il tempo di impostare un ambiente di test di carico di grandi dimensioni (in parte perché questa è ancora una soluzione di fallback, preferirei un server msg di battaglia dura). Qualche esperienza su quanti utenti ottieni per GB? Qualche limite difficile?

mia architettura permette anche di frammentare i server MSG, ma vorrei massimizzare le connessioni simultanee quanto l'overhead msg elaborazione della CPU è minimo.

+0

Questo è più difficile da accettare. Hai considerato un protocollo senza connessione come UDP? Dovresti scrivere i tuoi protocolli di riconoscimento, ma non dovrai mantenere le connessioni e non dovrai sostenere il sovraccarico della connessione. Ho scritto alcuni server distribuiti ad altissima velocità, ma non i clienti. – Gray

+0

FYI, nel frattempo l'ho implementato usando netty (vedi risposta sotto). – Daniel

+0

Cool @Daniel. Dovrò dare un'occhiata. Ho sentito cose buone su Netty ma non l'ho mai usato. – Gray

risposta

6

Nel frattempo ho implementato il mio server di messaggi utilizzando netty.io. Netty fa uso di Java NIO e scala molto bene. Per le connessioni inattive ottengo un footprint di memoria di 500 byte per connessione. Sto facendo solo un semplice inoltro dei messaggi (niente memorizzazione nella cache, archiviazione o altre cose di fantasia), ma con questo sono facilmente ottenendo 1000 - 1500 msg/sec (ogni mezzo KB) sulla piccola istanza di Amazon (1ECU/1,6 GB).

Altrimenti se si sta cercando un servizio (a pagamento), allora posso consigliare spire.io (non fanno pagare le connessioni ma hanno un prezzo più alto per messaggio) o pubnub (fanno pagare per le connessioni ma sono meno costosi per messaggio).

3

Devi cercare di più nell'architettura di creare tale ambiente. Prima di tutto, se si scrive la gestione dei socket da soli, non utilizzare Thread per Client Socket. Utilizzare metodi asincroni per la ricezione e l'invio di dati. WebSockets potrebbe essere troppo pesante se i messaggi sono piccoli. Poiché implementa il framing, che deve essere applicato singolarmente a ciascun messaggio per ogni socket (la cache può essere utilizzato per diverse versioni dei protocolli WebSockets), ciò rende più lento l'elaborazione di entrambe le direzioni: per ricevere e per inviare, soprattutto a causa del mascheramento dei dati .

È possibile creare milioni di socket, ma solo le tecnologie più avanzate sono in grado di farlo. Erlang è in grado di gestire milioni di connessioni ed è abbastanza scalabile. Se si desidera avere milioni di connessioni utilizzando altre tecnologie di livello superiore, è necessario pensare al clustering di ciò che si sta tentando di realizzare.

Ad esempio utilizzando il server gateway che terrà traccia di tutti i server di elaborazione. E avere dati di loro (IP, porte, carico (se sarà una rete interna, firewalling e port forwarding potrebbe essere utile qui). Il software client si connette a quel server gateway, server gateway controlla il server meno caricato e invia ip e porta al client Il client crea una connessione direttamente al server di lavoro utilizzando l'indirizzo fornito In questo modo si avrà un gateway che può anche gestire l'autorizzazione e non manterrà le connessioni a lungo, quindi una di esse potrebbe essere sufficiente. Pubblicazione di dati e mantenimento delle connessioni

Questo è molto correlato alle vostre esigenze e potrebbe non essere adatto alle vostre soluzioni.

+0

Ho trovato un articolo interessante per questo argomento: http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 Potrebbe essere interessante per te che l'autor è riuscito a ottimizzare il footprint dei mem usando una C lib che gestisce le connessioni per sostituire l'erlang. – Daniel

+0

Maksims Mihejevs: puoi rispondere alla domanda seguente, sarebbe utile per me.thanks.http: //stackoverflow.com/questions/23597203/instant-messaging-over-xmpp-or-websocket – Pradeep

Problemi correlati