nekokaburi Geschrieben 5. November 2008 Geschrieben 5. November 2008 Hallo Community! Folgende Ausgangslage: Ich habe einen Chat, dieser funktioniert grob so wie MSN, ICQ, etc. Also keinen Chatraum wo alle drinnen sind, sondern man chattet immer zu zweit und muss dafür die ID/Benutzernamen des anderen wissen. Das Ganze funktioniert eigentlich auch schon ganz ordentlich. (Manche Features die ich gerne hätte, wie z.B. Nachrichten an Personen verschicken die offline sind, fehlen halt noch *g*) Aber ich habe da leider einige Schwierigkeiten mit der Performance des Servers. Dieser läuft auf meinen Rechner, die Aufrufe der Clients erfolgen per Threads. D.h. der Thread des Clients fragt jede Sekunde nach, ob eine neue Nachricht für ihn vorliegt. Dies geschieht über RMI. Wenn ich jetzt >500 Clients connecten lasse (2 davon "chatten" jeweils miteinander) (automatisierter Test) dann geht der Server in die Knie (100% CPU Auslastung). Ich weiß, niemals nicht werden soviele Leute verbinden, aber ich würd gern wissen woran sowas liegen kann. ICQ ist ja auch mit Java progammiert worden, oder? Haben die dort so gewaltige Server, dass die diese Flut bewältigen können?! Ich selbst vermute das Problem ja größtenteils bei RMI, beim Marshelling/Unmarshelling, Serializieren, etc. geht bestimmt einiges an Zeit drauf, bin mir aber nicht sicher, kann dort das Problem liegen? Kann man etwas dagegen unternehmen? Oder hab ich nur absolut unperformant programmiert? (obwohl ich besonders darauf geachtet habe!) Sonstige Vorschläge? Vielen Dank, allein schon für's lesen *G* Grüße, Neko Bei Bedarf kann ich gerne auch Source-Code posten Zitieren
FinalFantasy Geschrieben 5. November 2008 Geschrieben 5. November 2008 Warum schickt der Server nicht einfach neue Nachrichten zum Client? Dieser hat sich ja vorher (nehme ich an) beim Server angemeldet, ist also vom Server aus erreichbar. Das was du gemacht hast, hört sich für mich nach Polling an. Weiß zwar nicht, ob das das Performanceproblem ist, aber das ist schonmal ungünstig. Wenn jeder Client 1x pro Sekunde pollt, dann hast du bei 500 Clients schon 500 abfragen, die der Server pro Sekunde abarbeiten muss, auch wenn keine einzige Nachricht versendet wurde. Zitieren
nekokaburi Geschrieben 5. November 2008 Autor Geschrieben 5. November 2008 Hallo, Erstmal danke für die schnelle Antwort Ja Polling (das Wort ist mir vorhin net eingefallen *g*). Wie kann ich denn über RMI etwas an den Client schicken? Die IP des Clients kann ich natürlich am Server rausfinden, aber dann...? Mit TCP-Sockets wollte ich eig. nicht arbeiten, weil RMI im vergleich so schön einfach funktioniert *gg* Geht es irgendwie per RMI von Server zu Client etwas zu übertragen, ohne das der Methodenaufruf vom Client ausgehen muss? Bisher dachte ich es muss so sein: Client -->(Anfrage) --> Server (wurschtelt rum und returned antwort) --> Client bekommt den Rückgabewert der Methode ? Zitieren
flashpixx Geschrieben 5. November 2008 Geschrieben 5. November 2008 Wie kann ich denn über RMI etwas an den Client schicken? [...] Client -->(Anfrage) --> Server (wurschtelt rum und returned antwort) --> Client bekommt den Rückgabewert der Methode Wird so leider nicht funktionieren, denn RMI ist eine aktive Componente. Nehmen wir an Du kennst von jedem Client die IP und hast auf jedem einen RMI Server laufen, die beiden Rechner sind hinter einer Firewall die NAT macht, dann hast Du keine Möglichkeit den Rechner aktiv von außen durch die Firewall zu erreichen, wenn kein Portforwarding eingerichtet ist. Du musst das System anders konzipieren HTH Phil Zitieren
nekokaburi Geschrieben 5. November 2008 Autor Geschrieben 5. November 2008 Das dachte ich auch, dass es mit Routern/Firewalls problematisch werden würde. Deshalb eben meine Lösung, per Threads in definierten Intervallen am Server anzufragen "was es neues gibt" Jemand eine Ahnung/Idee wie das z.B. bei ICQ gelöst wurde? (bevor jemand frägt, das Programm schreibe ich nur für mich als "training", wird maximal im Freundeskreis eingesetzt, also sollte es kein problem sein, von ICQ/MSN/Yahoo abzukupfern) Zitieren
FinalFantasy Geschrieben 5. November 2008 Geschrieben 5. November 2008 Ich hab keine Ahnung wie das RMI funktioniert, aber ICQ, Jabber usw. senden und empfangen denke ich mal über die gleiche Verbindung. Die Verbindung steht also schon, wenn der Server was zum Client schicken will. Es muss sich also keine neue Verbindung von Aussen durch Firewalls und Router bohren. Zitieren
Aiun Geschrieben 5. November 2008 Geschrieben 5. November 2008 evtl. als Stateless-Connection, ich weis nicht wie RMI im detail aussieht/funktioniert, aber ich würde mal eine einfache Socketverbindung mit möglichst geringem Datenaufkommen testen. ein IRC-Chatserver macht im prinzip nichts anderes, er filter wo/welche Nachricht hin kommt, mit dem unterschied das die verbindungen aktiv bleiben, und so riesig sind die Server nun auch nicht. Zitieren
flashpixx Geschrieben 5. November 2008 Geschrieben 5. November 2008 evtl. als Stateless-Connection, ich weis nicht wie RMI im detail aussieht/funktioniert, aber ich würde mal eine einfache Socketverbindung mit möglichst geringem Datenaufkommen testen. RMI ist nicht stateless. RMI erzeugt aber eine Menge Overhead, da hier im Grunde Objekte übertragen werden (Serialisierung usw). RMI sollte man nur im LAN einsetzen, da es sonst bei höheren Datenraten schnell zu Einbrüchen kommen kann. RMI ist ähnlich wie ein Webservice. Phil Zitieren
Aiun Geschrieben 5. November 2008 Geschrieben 5. November 2008 dann RMI ersetzen entsprechend hoch ist natürlich auch der aufwand auf serverseite die nachrichten zu verarbeiten. Plain-Socket oder ein "optimiertes" Kommunikationsprotokoll sollte helfen. Zitieren
nekokaburi Geschrieben 5. November 2008 Autor Geschrieben 5. November 2008 Mhm, schade! Dachte mir auch schon, das es an RMI liegen wird. Da kommt schon eine Menge Overhead zusammen... -Serialisierung der Daten (also müssen auch alle Superklassen mit gecheckt werden ob da Daten vorhanden sind) -Objekte statt primitive Datentypen -Ich glaube es ist sogar verschlüsselt? Gibt es irgendeine Alternative zu direkten TCP-Sockets? Also etwas das man ähnlich wie RMI verwenden kann (ohne die Automatische Serialisierung natürlich ) --> Objekte übertragen zu können ist halt schon eine super Sache... Zitieren
FinalFantasy Geschrieben 5. November 2008 Geschrieben 5. November 2008 (bearbeitet) Ich glaube nicht, dass RMI an sich das Problem ist. Ich glaube, dass das Polling schuld ist. Vielleicht noch das Polling in Verbindung mit RMI, aber nicht RMI alleine. Beim chatten kommt man auf geschätzte, mittlere Datenraten von 50-100Byte/s (mal geschätzt, wieviel man pro Sekunde zu tippen schafft). Selbst bei 200% Overhead und 500 Usern, die sich gleichzeitig die Finger wund schreiben, kommt man gerade auf 300Byte/s*500 ~ 150kb/s. Also wenn das RMI das nicht bewältigen können sollte (davon sind ja grad mal 1/3 Nutzdaten!!), dann ist das Protokoll meiner Meinung nach absolut unbrauchbar. Und das ist noch ne pessimistische Worst-Case-Überlegung. Aber wenns wirklich an dem RMI liegt, belehrt mich ruhig eines besseren. Und wenn RMI nicht stateless ist, dann steht die Verbindung ja dauerhaft. Ist die dann nicht bidirektional? Bearbeitet 5. November 2008 von FinalFantasy Zitieren
flashpixx Geschrieben 5. November 2008 Geschrieben 5. November 2008 Hallo, also nach Remote Method Invocation ? Wikipedia bin ich von einer "nicht stateless" Verbindung ausgegangen. Das Problem (aus eigener Erfahrung) ist, dass es mit wachsender Anzahl von Clients schon problematisch werden kann. Ein komplettes Objekt bzw den Objektaufruf zu übertragen, nur um eine Textnachricht zu versenden halte ich einfach für overkill (Verhältnis Nutzdaten zu Overhead). Vor allem ist mir nicht klar, warum ich ein komplettes Objekt aufrufen muss, nur um einen Text abzusetzen. Z.B. im Bereich Spieleentwicklung ist es unbrauchbar. Phil Zitieren
dr.dimitri Geschrieben 5. November 2008 Geschrieben 5. November 2008 Hi, wie wärs denn, wenn Du mit JMS arbeitest? Jeder Client schickt seine Messages zum Server, der entpackt die Message, schaut nach wohin sie gehört und versendet sie weiter. Damit hättest auch das problem der Speicherung erschlagen, denn sobald sich ein Client wieder anmeldet bekommt er sofort die Messages die sich in seiner Queue seit dem letzten Login angesammelt haben. Dim Zitieren
nekokaburi Geschrieben 6. November 2008 Autor Geschrieben 6. November 2008 Hi, wie wärs denn, wenn Du mit JMS arbeitest? Jeder Client schickt seine Messages zum Server, der entpackt die Message, schaut nach wohin sie gehört und versendet sie weiter. Damit hättest auch das problem der Speicherung erschlagen, denn sobald sich ein Client wieder anmeldet bekommt er sofort die Messages die sich in seiner Queue seit dem letzten Login angesammelt haben. Dim Hi! Kannst du mir das etwas genauer erklären? Wie kann der Server die Nachrichten denn weiterleiten? Geht das durch Firewall's und Router durch? Ist dort weniger Overhead? Kann ich auch Objekte verschicken oder nur Text? (Objekte machen es halt einfacher, weil ich ein Message-Objekt habe, welches neben den Text, noch den Empfänger, Sender sowei einen Datumsstempel enthält, wobei das nicht das Probleme wäre ) Ist JMS standardmäßig bei Java dabei? Welche Klassen sind dort wichtig, bzw wo gibt es eine gute Anleitung? Aber schonmal Danke für den Tipp überhaupt werde mir das am Wochenende mal zu gemüte führen *g* Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.