Zum Inhalt springen

Chat - Performance


nekokaburi

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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...

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 von FinalFantasy
Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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*

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...