Laden...

Multithreaded Socket Server

Erstellt von DerKami vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.937 Views
D
DerKami Themenstarter:in
9 Beiträge seit 2016
vor 8 Jahren
Multithreaded Socket Server

Moin,

Ich wollte mal nach ein paar Erfahrungswerten fragen bezüglich einer Multithreaded Server Umgebung.

Es geht eigentlich genau um die Umsetzung. Ich habe da jetzt 2 folgende Ideen:

1)
1 Hauptthread zum Verwalten
1 Receiver für die Verbindungen
Je 2 Unterthreads beinhaltet die jeweils Blockend lesen, bzw Blockend schreiben.

2)
1 Hauptthread zum Verwalten
1 Receiver für die Verbindungen
1 Clientthread der nicht blockiert und ständig prüft und arbeitet und versendet.

Ich halte die 2. Idee für die schlechtere weil eben die Threads ständig laufen... In der 1. Variante hätte ich zwar "mehr" zum Verwalten, ist aber meiner Meinung nach die Performantere.

Habt ihr da noch andere Ansätze? Bin ich vllt. auf dem Holzweg?
Über n paar Erfahrungen wäre ich Dankbar.

Gruß
Kami

16.835 Beiträge seit 2008
vor 8 Jahren

Was genau hast Du vor? Wieso das selbst umsetzen statt vorhandene Technologien zu verwenden?

D
DerKami Themenstarter:in
9 Beiträge seit 2016
vor 8 Jahren

Moin,

ich wollte mir ein paar flexible Klassen für n Binary TCP Transfer schreiben.
Der Einsatzzweck reicht von ein paar Clients bis hin zu mehreren 100 bis 1000 Clients.
Das ganze als Übung um wieder in das Thema einzusteigen und um ein wenig freier in der Möglichkeit der Gestaltung und Steuerung zu sein.
Oftmals wird man bei bereits vorgefertigten Lösungen in ein Schema gesteckt, welches zu unflexibel ist. Aber wenn du da was kennst, nutze ich auch Tech die es bereits gibt.
Der Server wird Service in ein System eingebettet und unter Umständen wird es mehrere Nodes geben, ohne einen Masterserver, die Nodes kennen sich aber untereinander und teilen die Lasten selbst auf.

Ich hab damals mit Pascal ein Singlethreaded Binary TCP Protokoll geschrieben, von daher ist es nicht so, als würde ich mich komplett nicht auskennen. Ich hatte auch schon überlegt die Kommunikation rein über WebApi Schnittstellen laufen zu lassen, aber das ist bei Echtzeitrelevanten-Inhalten dann nicht mehr ganz so tauglich.

Gruß
Kami

16.835 Beiträge seit 2008
vor 8 Jahren

Sobald TCP im Spiel ist, ist es sowieso nicht mehr Echtzeit. Das nur nebenbei...
Mir ist immer noch nicht klar, was das werden soll. Wenns in Richtung Chat geht, dann würde ich WebSockets auf SignalR-Basis verwenden.

Sockets sind keine Garantie für flexible Umsetzungen und umgekehrt sind Frameworks nicht gleich unflexibel.
Kommt auf die Umsetzung an..

D
DerKami Themenstarter:in
9 Beiträge seit 2016
vor 8 Jahren

Ich brauche, ein Glück, keine "harte Echtzeit".

Was damit realisiert werden soll ist ungefähr folgendes:

Es gibt im Netzwerk verschiedene Rechner/Server die eben einen solchen Dienst als Node haben.
Dieser Server/Node soll bestimmte Aufgaben erledigen, quasi Tasks für die Clients erledigen. Diese Tasks können unter Umständen ziemlich Zeitaufwändig sein, und zum Teil nicht parallelisiert werden. Das bedeutet jeder von ihnen hat eine Queue, die abgearbeitet werden muss. Der Client muss dann aber in jedem Fall eine Antwort erhalten.

Wenn nun ein Client sich mit einen Node verbindet, dieser allerdings ausgelastet ist, wird er an den nächsten Verwiesen. Die Nodes untereinander können kommunizieren um ihre Last zu verteilen. Die Clients interessiert gar nicht wo sie landen, da jeder dasselbe kann, nur eben anders Ausgelastet ist.

Da die Clients aber eben auch mehrere Tasks auszuführen haben, könnte es eben sein, dass ein Client z.b. an 3 verschiedene Nodes zeitintensive Tasks ausführen lässt, die er Überwachen muss. Dauer, Nummer in der Queue, Rückgabe, Abbruch, etc.

Für einen Teil der Tasks würde auch ein Polling reichen. Es gibt aber eben auch Tasks bei dem das Polling nicht reicht und ich einen Push brauche, weshalb ich in dem Fall eine offene Verbindung präferiere. Gerade wenn es um serialisierte Tasks geht, die ich durch die Nodes parallelisieren kann, brauche ich, um eine möglichst hohe Auslastung zu schaffen, eine aktive Kommunikation.

Um das ganze noch weiter zu Konkretisieren auf ein Spezifisches Beispiel:
Es müssen 100000 Dokumente (PDFS) erzeugt werden. Die -komponente dazu kann eben nur eins nach dem anderen Drucken, Druckzeit ca. 1 Sekunde. Der Client kann sich nun die Nodes suchen um seine Tasks zu verteilen. Bei 20 Nodes wären das 20 gleichzeitige Dokumente, was die Zeit von ca 27,7h auf 1,3h reduziert.
Das heißt dies wäre eine Queue die nicht Parallelisierbar ist pro Node, andere Aufgaben könnten jedoch weiterhin nebenher laufen. Unteranderem auch von anderen Clients.

Ich hoffe der Sinn dahinter kommt ein bisschen besser an.

Gruß
Kami

16.835 Beiträge seit 2008
vor 8 Jahren

Ich stimm Dir in Deiner Argumentation zu; kann es jetzt nachvollziehen - weiß jetzt, was Du vor hast.
Stimme Dir allerdings bei der Infrastruktur nicht zu.

Im Grunde möchtest Du eine horizontale Skalierung, wie sie heute in vielen Bereichen (zB. Cloud) üblich ist.
Wieso müssen sich denn die Nodes kennen? Nur für die Verteilung?
Wieso gibt es keine Queue, in der die Aufgaben liegen und sich die Nodes selbstständig die Aufgaben abholen?

Hatte gestern ein Gespräch mit einem Forenmitglied (weismat) über Akka.NET; und das hier könnte tatsächlich nen Anwendungsfall für Akka sein.
Gerade wenn Du eine Antwort haben musst, dann musst Du Dir auch über potentielle Fehler Gedanken machen.
Was ist wenn eine Node mitten in der Verarbeitung abraucht? Wer bekommt das mit? Was passiert mit dem Task? Ist er verloren?

Glaub mir. Das willst Du nicht alles selbst entwickeln.
Entwickle das, was Dir einen Benefit gibt: Deine Business Logik. Aber bei der Infrastruktur ist es besser was vorhandenes wie Akka zu nehmen.

Um nochmal das Thema Cloud und hier Azure zu erwähnen: hier würde man das über die Service Fabric umsetzen, die quasi das Äquivalent von Akka darstellt.
Damit kannst Du das ganze erst mal ausprobieren und das System als solches evaluieren, ohne, dass Du was bei Dir aufbauen musst.

Wenn Dir das dann gefällt, dann kannst Du es eben in der Cloud laufen lassen via Service Fabric oder eben bei Dir OnPremise mit Akka.NET umsetzen.

D
DerKami Themenstarter:in
9 Beiträge seit 2016
vor 8 Jahren

Akka.net klingt wirklich interessant, wenn's mir die Kommunikation zwischen Clients und Server ermöglicht.

Ich muss allerdings auch Mobiledevices mit einbeziehen, wobei ich glaube ich dort eher das Polling präferiere.

Vielleicht ist der Ansatz mit der Hauptqueue gar nicht mal so verkehrt, ich müsste zwar einige Prozesse umdenken und anders vom Ablauf gestalten, hätte aber wahrscheinlich weniger Fehlerfälle zu betrachten.

Danke für den Anstoß.

Gruß
Kami

2.298 Beiträge seit 2010
vor 8 Jahren

Ich würde dir auch eher dazu raten, eine globale Queue zu verwenden in welche die Clients Tasks eintragen, die Nodes sich Tasks herausholen und bearbeiten und anschließend den Abarbeitungszustand an die Queue zurück geben. Die Queue informiert dann den Client über die Abarbeitung.

Im Anhang mal ganz grob wie das bei 2 Clients und 2 Nodes aussehen könnte (Ich weiß, kein 100% reines UML).

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

W
872 Beiträge seit 2005
vor 8 Jahren

Bei Akka gibt es als Untermodul Akka Remoting, das die Kommunikation zwischen Client und Server anbietet - dort werden dann auch verschiedene Transports unterstützt.
Wenn Du Mobile Devices mit Polling unterstützst, dann brauchst Du in Akka einen Scheduler, der dann die regelmässigen Nachrichten an die Clients auslöst.