2012-04-11 6 views
6

Ich baue ein verteiltes System, das aus potenziell Millionen von Clients besteht, die alle eine offene (vorzugsweise HTTP) Verbindung haben müssen, um auf einen Befehl vom Server zu warten (der woanders läuft) . Die Last von Nachrichten/Commands wird nicht sehr hoch sein, vielleicht eine Nachricht/Sekunde/1000 Clients, was bedeutet, dass es 1000 msg/sec @ 1 Million Clients wäre. => es geht im Grunde um die gleichzeitigen Verbindungen.Server Push für Millionen von gleichzeitigen Verbindungen

Die Anforderungen sind auch einfach. One-Way-Messaging (Server-> Client), nur 1 Client pro "Channel".

Ich bin ziemlich offen in Bezug auf Technologie (xmpp/websockets/comet/...). Ich benutze Google App Engine als Server, aber ihre "Kanäle" funktionieren bei mir leider nicht (zu niedrige Quoten und kein Java-Client). XMPP war eine Option, ist aber ziemlich teuer. Bisher verwendete ich URL Fetch & pubnub, aber sie begannen gerade, für Verbindungen aufzuladen (große Zeit).

So:

  1. Kennt jemand einen Dienst aus, dass es für mich, dass in einem erschwinglichen Weise tun kann? Die meisten, die ich gefunden habe, beschränken oder stark für Verbindungen aufladen.

  2. Irgendwelche Erfahrungen mit der Implementierung eines solchen Servers? Ich habe das bereits getan und es funktioniert ziemlich gut (basierend auf Tomcat & NIO), aber ich hatte noch nicht die Zeit, um tatsächlich eine große Belastung Testumgebung einzurichten (teilweise weil dies immer noch eine Ausweichlösung ist, würde ich bevorzugen ein kampfgehärteter msg Server). Irgendwelche Erfahrungen, wie viele Nutzer Sie pro GB erhalten? Irgendwelche harten Grenzen?

Meine Architektur ermöglicht auch den msg-Server fragmentieren, aber ich mag die gleichzeitigen Verbindungen maximieren weil das msg-Verarbeitungs-CPU-Overhead minimal ist.

+0

Dies ist eine härtere zu akzeptieren. Haben Sie ein verbindungsloses Protokoll wie UDP in Betracht gezogen? Sie müssten Ihre eigenen Ack-Protokolle schreiben, aber dann müssten Sie die Verbindungen nicht aufrechterhalten, und Sie müssen nicht den Verbindungsoverhead in Kauf nehmen. Ich habe einige verteilte Server mit sehr hohem Durchsatz geschrieben, aber keine Kunden. – Gray

+0

FYI, ich habe es inzwischen mit netty implementiert (siehe Antwort unten). – Daniel

+0

Cool @ Daniel. Ich muss es überprüfen. Ich habe gute Dinge über Netty gehört, aber nie benutzt. – Gray

Antwort

6

Ich habe inzwischen meinen eigenen Nachrichtenserver mit netty.io implementiert. Netty nutzt Java NIO und skaliert extrem gut. Für inaktive Verbindungen erhalte ich einen Speicherbedarf von 500 Bytes pro Verbindung. Ich mache nur eine sehr einfache Nachrichtenweiterleitung (kein Caching, Speicher oder anderes schickes Zeug), aber mit dem erreiche ich leicht 1000 - 1500 msg/sec (jede halbe KB) auf der kleinen Amazon-Instanz (1ECU/1,6GB).

Sonst, wenn Sie nach einem (bezahlten) Service suchen, dann kann ich spire.io empfehlen (sie berechnen nicht für Verbindungen, aber haben einen höheren Preis pro Nachricht) oder pubnub (sie berechnen für Verbindungen, sind aber billiger pro Nachricht).

3

Sie müssen in der Architektur solcher Umgebung mehr suchen. Wenn Sie zuerst die Socket-Verwaltung selbst schreiben, verwenden Sie nicht Thread pro Client-Socket. Verwenden Sie asynchrone Methoden zum Empfangen und Senden von Daten. WebSockets sind möglicherweise zu schwer, wenn Ihre Nachrichten klein sind. Da Framing implementiert wird, das auf jede Nachricht einzeln für jeden Socket angewendet werden muss (Caching kann für verschiedene Versionen von WebSockets-Protokollen verwendet werden), werden beide Richtungen langsamer verarbeitet: für Empfang und Senden, insbesondere wegen Datenmaskierung .

Es ist möglich, Millionen von Sockets zu erstellen, aber nur die modernsten Technologien sind dazu in der Lage. Erlang kann Millionen von Verbindungen verarbeiten und ist ziemlich skalierbar. Wenn Sie Millionen von Verbindungen mit anderen Technologien der höheren Ebene haben möchten, dann müssen Sie über Clustering von dem nachdenken, was Sie erreichen möchten.

Zum Beispiel mit Gateway-Server, der alle verarbeitenden Server verfolgen wird. Und haben Sie Daten von ihnen (IP, Ports, laden (wenn es ein internes Netzwerk sein wird, Firewalling und Port-Weiterleitung könnte hier nützlich sein). Client-Software verbindet sich mit diesem Gateway-Server, Gateway-Server überprüft die am wenigsten geladenen Server und sendet IP-und Port zum Client Der Client stellt eine Verbindung direkt zum funktionierenden Server unter Verwendung der bereitgestellten Adresse her Auf diese Weise haben Sie ein Gateway, das auch mit Autorisierung umgehen kann, und hält Verbindungen nicht lange, also könnte eine von ihnen genug sein Veröffentlichung von Daten und Aufrechterhaltung von Verbindungen

Dies hängt sehr mit Ihren Anforderungen zusammen und ist möglicherweise nicht für Ihre Lösungen geeignet.

+0

Ich fand einen interessanten Artikel zu diesem Thema: http://www.metabrew.com/article/a-milli-user-comet-application-with-mochiweb-part-1 Könnte für Sie interessant sein, dass der Autor es schaffte, weiter zu machen Optimieren Sie den mem-Footprint, indem Sie eine C-lib verwenden, die die Verbindungen übernimmt, die erlang ersetzen. – Daniel

+0

Maksims Mihejevs: kann pls Antwort der folgenden Frage, es wäre hilfreich für mich.thanks.http: //stackoverflow.com/questions/23597203/instant-messaging-over-xmpp-oder-websocket – Pradeep

Verwandte Themen