Laden...

effizienter (benutzerdefinierter) RPC Mechanismus

Erstellt von zommi vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.822 Views
zommi Themenstarter:in
1.361 Beiträge seit 2007
vor 13 Jahren
effizienter (benutzerdefinierter) RPC Mechanismus

Hallo,

für eine Art Load-Balancer programmiere ich gerade eine Server-Anwendung, die Arbeit auf mehrere Prozesse verteilt.
(Warum Prozesse statt Threads/AppDomains steht nicht zur Diskussion - die Verwendung von nativem, unsicherem Code erfordert das Kapseln in eigene Prozesse)

Nun müssen vom Load-Balancer bestimmte Objekte (Files, Sockets, etc.) an diese Worker-Prozesse übermittelt werden. Da man Handles (oder unter Linux+Mono die FileDeskrtiptoren) aber nicht einfach über Prozessgrenzen kopieren/marshallen kann, benötigt man spezielle API-Aufrufe und sendet die "duplizierten" Handles/Filedeskriptoren dann über Pipes/Sockets rüber.

Das klappt soweit auch.
Allerdings möchte ich nun die Kommunikation zwischen LoadBalancer und Workern gerne etwas erweitern. Status abfragen, ...
Und da ich weder ein festes/schlecht erweiterbares Protokoll entwickeln möchte und ebensowenig einen kompletten RPC-Mechanismus neu erfinden will, würde ich gerne eine bestehende Technologie verwenden.

Was könnte man mir hierfür empfehlen? Remoting ? WCF ?
Performance ist durchaus relevant. Und mir scheint WCF irgendwie "schwergewichtiger" Oder trügt da der Eindruckt?

Wichtig ist aber vor allem: Ich fänd es gut, wenn diese RPC-Mechanismen mit meinen Handle-Verschick-Aktionen harmonieren. Also am besten ein und der selbe Kanal (Socket/Pipe) genutzt wird. Geht das? Sonst bräuchte ich zu jedem Worker zwei Kanäle (einen für die Handles und einen für das reine Remoting)
Ich hab schon etwas in diese Richtung recherchiert und anscheinend könnte ich bei Remoting eigene IChannel/IMessageSink/... implementieren. Das riecht aber nach mächtig Aufwand.

Ich wäre für Empfehlungen, Tipps oder sonstigen Anregungen eurerseits überaus dankbar.
beste Grüße
zommi

3.728 Beiträge seit 2005
vor 13 Jahren
Rpc

Hallo zommi,

wenn ich Dich richtig verstanden habe, möchtest Du, dass Remoting bzw. WCF den selben Socket nutzen, wie Deine vorhandene manuelle Implementierung auf Socket-Basis.

Out-of-the-box funktioniert das nicht, da sowohl WCF als auch Remoting ihre benötigten Sockets/Pipes unter der Haube selbst verwalten. Du hast von außen keinen Einfluss darauf, welcher Socket verwendet wird und wann dieser wieder geschlossen wird.

Es gibt aber sowohl bei Remoting als auch bei WCF die Möglichkeit eigene Kanaltypen und andere Erweiterungen zu schreiben. Remoting ist im allgemeinen sehr viel leichtgewichtiger. Der Aufwand sollte sich bei Remoting in Grenzen halten. Hier ein Beispiel für einen benutzerdefinierten Remoting-Kanal: http://www.winsocketdotnetworkprogramming.com/clientservernetremotingnetwork12f.html
Ob Du da Deinen bestehenden Socket wirklich mit rein wursteln kannst, weiss ich nicht. Hab selber noch keinen eigenen Kanal geschrieben. Ich hätte dabei großes Bauchweh.

WCF würde ich nur empfehlen, wenn folgende Punkte eine Rolle spielen:*Interoperabilität (SOAP, etc.) *Kommunikation übers Internet (evtl. durch Firewalls) *Notwendigkeit von HTTPS ohne IIS verwenden zu müssen

Im Vergleich zu Remoting ist WCF ein umständlicher Kram. Allerdings ein sehr mächtiger umständlicher Kram.

Andere Frage, warum verschickst Du nicht auch Deine Handles mit Remoting? Oder muss Dein Load-Balancer direkt mit unmanaged Code kommunizieren (dann geht das natürlich nicht)? Alles was Du über Sockets schicken kannst, kannst Du auch über Remoting schicken. Du hättest dann eine einheitliche Technologie.

zommi Themenstarter:in
1.361 Beiträge seit 2007
vor 13 Jahren

Hi Rainbird,

wenn ich Dich richtig verstanden habe, möchtest Du, dass Remoting bzw. WCF den selben Socket nutzen, wie Deine vorhandene manuelle Implementierung auf Socket-Basis.

Genau!

Remoting klingt wohl gut. WCF scheint zu viel des Guten für meinen Anwendungsfall zu sein.
Ob ich nun doch zwei Sockets/Pipes parallel verwende, oder ne eigene Kanal-Implementierung verwende, muss ich nun schaun - was praktikabler ist. Und danke für den Link.

Andere Frage, warum verschickst Du nicht auch Deine Handles mit Remoting? Oder muss Dein Load-Balancer direkt mit unmanaged Code kommunizieren (dann geht das natürlich nicht)? Alles was Du über Sockets schicken kannst, kannst Du auch über Remoting schicken. Du hättest dann eine einheitliche Technologie.

Stimm schon. Unter Windows geht das auch sehr gut. Aber bei Linux+Mono gibts leider kein DuplicateHandle und Konsorten.
Dort muss man relativ umständlich über UnixDomainSockets seine FileDeskriptoren neben den Daten als "Ancillary Data" zu einem DatenPaket mittels sendmsg übertragen. (Mein jetziger Weg) Und das macht Remoting eben nicht mit 😉

Aber ich werd mir nun mal näher Remoting anschauen.

beste Grüße
zommi

Gelöschter Account
vor 13 Jahren

irgendwie hört sich das nach einem monofähigen lightweight bizztalk-server an.

warum verschickst du die handles von dateien? warum nciht den pfad? oder warum nciht den relevanten inhalt?

zommi Themenstarter:in
1.361 Beiträge seit 2007
vor 13 Jahren

Hi,

warum verschickst du die handles von dateien?

Weil die Worker-Prozesse mit diesen arbeiten sollen 😉

warum nciht den pfad?

Weil der Worker-Prozess die Rechte haben müsste, diese Datei zum lesen/schreiben zu öffnen. (Und das sind mir zu viel Rechte 😉 )

oder warum nciht den relevanten inhalt?

Wäre zu großer Overhead, was den LoadBalancer an sich nur unnötig belasten würde.

Aber du hast schon Recht, bei Dateien macht das wenig Sinn. Wichtiger für meinen Fall sind auch Sockets (und deren Handles). Und damit ein WorkerProcess auch die Anfrage eines Kunden bearbeiten kann, benötigt er eben genau diesen Socket. Deshalb muss ich Handles+FileDeskriptoren verschicken.

beste Grüße
zommi

3.728 Beiträge seit 2005
vor 13 Jahren

Dort muss man relativ umständlich über UnixDomainSockets seine FileDeskriptoren neben den Daten als "Ancillary Data" zu einem DatenPaket mittels sendmsg übertragen. (Mein jetziger Weg) Und das macht Remoting eben nicht mit 😉

Damit Du es über Sockets übertragen kannst, muss Du es vorher in ein byte[] serialisieren. Über Sockets werden nur Bytes übertragen. Du kannst ein byte[] aber auch mit Remoting übertragen. Möglicherweise musst Du die Serialisierung vorher manuell durchführen, das ist aber kein Beinbruch (ca. 2 Zeilen Code). Ich verstehe deshalb nicht, warum die Datenübertragung mit Remoting nicht klappen sollte?

Gelöschter Account
vor 13 Jahren

@Rainbird:

ich habe es so verstanden, das sein loadbalancer nur "vermitteln" soll. daher würde er eine anfrage auf einem socket bekommen und dann würde er den socket jemanden anderen schicken nach dem motto "hier kümmere dich darum" und will dann nichts weiter damit zu tun haben.

wenn er die bytearrays hin und herschicken müsste, dann müsste er ja sich um die übermittlung während des gesamten interaktionszeitraumes kümmern, was in der masse einen erheblichen overhead bereiten würde.