2009-07-30 16 views
8

Ich habe Clients, die alle mit einem einzelnen Serverprozess verbinden müssen. Ich verwende UDP-Erkennung für die Clients, um den Server zu finden. Ich habe den Client und den Server IP-Adresse und Port-Nummer austauschen, so dass eine TCP/IP-Verbindung nach Abschluss der Erkennung hergestellt werden kann. Auf diese Weise wird die Paketgröße klein gehalten. Ich sehe, dass dies auf eine von zwei Arten mit UDP erfolgen könnte:UDP Server Discovery - Sollen Clients Multicasts senden, um Server zu finden, oder sollte der Server reguläre Beacons senden?

  • Jeder Client sendet eine eigene Multicast-Nachricht auf der Suche nach dem Server, die der Server dann antwortet. Der Client kann das Senden dieser Multicast-Nachricht in regelmäßigen Intervallen (falls der Server ausgefallen ist) wiederholen, bis der Server antwortet.
  • Der Server sendet in regelmäßigen Abständen eine Multicast-Nachricht Beacon. Die Clients abonnieren die Multicast-Gruppe und empfangen auf diese Weise die Multicast-Nachricht des Servers und schließen die Erkennung ab.
  • In 1. wenn es viele Clients gibt, dann würden anfangs viele Multicast-Nachrichten übertragen werden (eine von jedem Client). Nur der Server würde die Multicast-Nachrichten von den Clients abonnieren und empfangen. Sobald der Server auf den Client geantwortet hat, hört der Client auf, die Multicast-Nachricht zu senden. Sobald alle Clients ihre Entdeckung des Servers abgeschlossen haben, werden keine weiteren Multicast-Nachrichten über das Netzwerk übertragen. Wenn der Server jedoch nicht aktiv ist, sendet jeder Client eine Multicast-Nachricht in Intervallen aus, bis der Server wieder aktiv ist und antwortet.

    In 2. nur der Server würde eine Multicast-Nachricht Beacon in regelmäßigen Abständen senden. Diese Nachricht würde am Ende an alle Clients weitergeleitet werden, die die Multicast-Gruppe abonniert haben. Sobald die Clients das Paket empfangen haben, wird der UDP-Abhörsocket des Clients geschlossen und sie sind nicht länger an der Multicast-Gruppe angemeldet. Der Server muss jedoch weiterhin das Multicast-Beacon senden, damit neue Clients es erkennen können. Es würde fortfahren, das Beacon in regelmäßigen Intervallen auszusenden, ungeachtet dessen, ob irgendwelche Clients ihre Entdeckung erfordern oder nicht.

    Also, ich sehe Pro und Kontra, wie auch immer. Es scheint mir, dass # 1 anfänglich zu einer stärkeren Belastung führen würde, aber diese Last reduziert sich schließlich auf Null. In # 2 würde der Server für immer einen Beacon senden.

    UDP und Multicast ist ein ziemlich neues Thema für mich, also bin ich daran interessiert, herauszufinden, welcher der bevorzugte Ansatz wäre und was zu weniger Netzwerkbelastung führen würde.

    +1

    Haben Sie explizit entschieden, keine standardmäßigen Service Discovery-Mechanismen zu verwenden? – Duck

    +3

    Wenn Sie Standard-Service-Discovery-Mechanismen sagen, können Sie bitte klarstellen, was Sie davon halten. Ich bin dabei, zu "entdecken", was meine Optionen sind und den besten Ansatz zu nehmen. – Elan

    Antwort

    2

    Ich würde Methode # 2 empfehlen, da es wahrscheinlich ist (je nach Anwendung), dass Sie weit mehr Clients als Sie Server haben werden. Wenn der Server einen Beacon aussendet, sendet er nur ein einziges Paket, anstatt nur ein Paket für jeden Client. Der andere Vorteil dieser Methode besteht darin, dass es den Clients erleichtert, festzustellen, wann ein neuer Server verfügbar wird oder wann ein vorhandener Server das Netzwerk verlässt, da sie keine Verbindung zu jedem Server aufrechterhalten müssen Server, oder weiter jeden Server abfragen, um herauszufinden.

    1

    Beide sind gleichermaßen brauchbare Methoden.

    Das Argument für Methode # 1 wäre, dass Clients im normalen Prinzip Anfragen initiieren, und Server sie abhören und darauf reagieren. Das Argument für Methode # 2 wäre, dass der Punkt von Multicast so ist, dass ein Host ein Paket senden kann und von vielen Clients (Eins-zu-Viele) empfangen werden kann, also ist es das Gegenteil # 1.

    OK, wenn ich darüber nachdenke, bin ich tatsächlich auf # 2 gezogen, Server-initiierte Beacon. Das Problem mit # 1 ist, dass Clients Beacons senden und sie sich mit dem Server verbinden, aber der Server entweder offline geht oder seine IP-Adresse ändert.

    Wenn der Server wieder betriebsbereit ist und sein erstes Beacon sendet, werden alle Clients gleichzeitig benachrichtigt, um die Verbindung wiederherzustellen, und Ihr gesamtes System ist sofort wieder betriebsbereit. Mit # 1 müssten alle Clients einzeln erkennen, dass der Server verschwunden ist, und sie würden gleichzeitig mit dem Multicasting beginnen, bis sie wieder mit dem Server verbunden sind. Wenn Sie 1000 Clients und 1 Server hätten, wäre Ihre Netzwerklast buchstäblich 1000-mal größer als Methode 2.

    Ich weiß, dass diese Nachrichten höchstwahrscheinlich klein sind, und 1000 Pakete gleichzeitig sind nichts für ein UDP-Netzwerk, aber nur vom Designstandpunkt aus fühlt sich # 2 besser an.

    Edit: Ich fühle mich wie ich eine Split-Persönlichkeitsstörung hier entwickeln, aber nur an einen starken Punkt, warum # 1 wäre ein Vorteil sein ... Wenn Sie jemals eine Art von natürlichen implementieren wollte Load Balancing oder Scaling mit mehreren Servern, Design # 1 funktioniert dafür gut. Auf diese Weise kann der erste "verfügbare" Server auf das Beacon des Clients reagieren und sich mit ihm verbinden, im Gegensatz zu # 2, wo alle Clients zum Beaconing-Server springen.

    1

    Ihre Option # 2 hat eine große Einschränkung in der Annahme, dass der Server mehr oder weniger direkt mit jedem möglichen Client kommunizieren kann. Abhängig von der genauen Netzwerkarchitektur Ihres Betriebssystems ist dies möglicherweise nicht der Fall. Zum Beispiel können Sie davon abhängig sein, dass alle Router und VPN-Software und WANs und NATs und alle anderen Dinge, mit denen die Leute Netzwerke verbinden, tatsächlich mit Multicast-Beacon-Paketen umgehen können.

    Mit # 1 gehen Sie davon aus, dass die Clients ein UDP-Paket an den Server senden können. Dies ist eine durchaus vernünftige Erwartung, insbesondere wenn man bedenkt, dass der Client als nächstes eine TCP-Verbindung zum selben Server herstellt.

    Wenn der Server ausfällt und der Kunde will, um herauszufinden, wenn es wieder nach oben ist, seine sicherexponential backoff verwenden sonst werden Sie das Netzwerk mit einem Paket Sturm nach unten einem Tag!

    +1

    Option # 1 basiert auch auf dem Senden eines Multicast-Pakets, es geht nur in die entgegengesetzte Richtung - also gelten ähnliche Vorbehalte. – caf

    +0

    Mit # 1, wenn der Server ausfällt, würden wir eine plötzliche Spitze in Multicast-Nachrichten von Clients bekommen. Jedoch würde nur der Server die Multicast-Gruppe abonnieren. Also, wenn ich das richtig verstehe, würde der Router alle Nachrichten an einen einzigen Endpunkt (den Server) routen. Mit # 2 könnten Sie mehr als 100 Clients haben, die den Multicast des Servers abonniert haben und der Router würde mehr als 100 Nachrichten an jeden der Client-Endpunkte routen. Wäre nicht die Netzwerklast in beiden Fällen gleich? Wäre ein Empfang von mehr als 100 Paketen, die gleichzeitig auf dem Server (# 2) ankommen, ein Problem? Dies wird allmählich/schnell auf 0 reduziert. – Elan

    +0

    Korrektur: Eigentlich würden mit # 1 die Client-Pakete nicht alle gleichzeitig bei den Routern und dem Server ankommen. Die Clients haben jeweils unterschiedliche Startzeiten. Das Client-Beacon könnte beispielsweise in 30-Sekunden-Intervallen übertragen. Jedes Paket ist möglicherweise 200 Bytes groß. Selbst mit 1000 Paketen hätten wir nicht genügend Zeit (Computer), um die Router und den Server zu verarbeiten? Der Client könnte den Beacon auch verlangsamen, wenn zu viele fehlgeschlagene Versuche vorliegen. – Elan

    4

    Ich habe die Option # 2 in der Vergangenheit mehrmals verwendet. Es funktioniert gut für einfache Netztopologien. Es gab einige Durchsatzprobleme, wenn UDP-Datagramme die Ethernet-MTU überschritten, was zu einer großen Fragmentierung führte. Das größte Problem, das wir gesehen haben, ist, dass die Multicast-Erkennung in größeren Topologien zusammenbricht, da viele Router so konfiguriert sind, dass Multicast-Datenverkehr blockiert wird.

    Die issue that Greg alluded to ist eher wichtig zu berücksichtigen, wenn Sie Ihre Protokoll-Suite entwerfen. Sobald Sie über einfache Netzwerktopologien hinausgehen, müssen Sie Lösungen für address translation, IP spoofing und eine ganze Reihe anderer Probleme im Zusammenhang mit der Übergabe von Ihrer Discovery-Schicht an Ihre Kommunikationsschicht finden. Die meisten von ihnen müssen sich konkret damit befassen, wie sich Ihr Server identifiziert und sicherstellen, dass die Identifikation etwas ist, das ein Kunde nutzen kann.

    Wenn ich es wieder tun könnte (wie oft haben wir diesen Satz ausgesprochen), würde ich nach standardbasierten Erkennungsmechanismen suchen, die die Rechnung erfüllen und damit beginnen, die anderen Protokoll-Suite-Probleme zu lösen. Das letzte, was Sie wirklich tun möchten, ist ein wirklich gutes Erkennungsschema, das die Woche nach der Bereitstellung aufgrund einer unvorhergesehenen Netzwerktopologie durchbricht. Google service discovery für eine Startliste. Ich persönlich tendiere dazu, DNS-SD, aber es gibt eine Menge anderer Optionen zur Verfügung.

    +0

    Dies ist eine sehr hilfreiche Information. Ich entwickle ein Produkt in C#, das für Kunden bereitgestellt wird. Unnötig zu sagen, dass Netzwerk- und Router-Konfigurationen von Standort zu Standort stark variieren können. Auf Clientarbeitsstationen und einem einzelnen Serverhost wird ein Clientdienst ausgeführt. WCF wird für normale Nachrichten verwendet. DNS-SD ist ein interessanter Vorschlag, ich muss mehr darüber nachdenken. Ich fand einen interessanten Artikel: http://www.smallegan.com/blog/?p=28 – Elan