2012-11-29 14 views
8

Ich entwickle derzeit ein einfaches P2P-Netzwerk als Übung. Jeder Knoten im Netzwerk sendet Heartbeats an eine Teilmenge der anderen Knoten, um Knoten zu erkennen, die das Netzwerk verlassen haben. Neben den Heartbeat-Paketen sende ich Pakete, wenn neue Knoten dem Netzwerk beitreten/verlassen, wenn sie eine Ressource (kleine Textdateien) usw. suchen wollen. Alle Pakete sind UDP-Pakete.Der beste Weg, um viele eingehende Pakete zu behandeln

Immer wenn ich ein Paket erhalte, starte ich einen neuen Thread, der dieses spezielle Paket behandelt. Ich mache mir jedoch Gedanken über die Anzahl der Threads, die ich während einer Anwendungslebensdauer starte, was ziemlich viel ist (vor allem wegen der Herzschläge). (Es besteht auch die Gefahr von Deadlocks und dergleichen, die ich gerne vermeiden würde).

Ich dachte über eine Warteschlange oder etwas, wo ich alle eingehenden Pakete und einen einzigen Thread alle Pakete nacheinander aus dieser Warteschlange (etwas wie das Producer-Consumer-Muster). Ich möchte, dass die Pakete schnell bearbeitet werden, so dass der Absender das Paket nicht verloren sieht.

Was ist der beste Weg, um viele verschiedene eingehende Pakete zu behandeln, ohne für jeden einen neuen Thread zu starten? Soll ich mit dem was ich habe, den Produzenten verzehren oder etwas anderes?

+1

Sicher. Verwenden Sie den Producer-Consumer mit einer LinkedList. Der einfachste Weg, den ich mir vorstellen kann. – DankMemes

+0

Sie können mit etwas altmodischem beginnen, wie Sie es selbst genannt haben, einige Benchmarks machen und dann etwas Neues ausprobieren, wie "Disruptor" (http://lmax-exchange.github.com/disruptor/) und dann noch etwas mehr Benchmarks. –

+1

Es kann helfen, "viele verschiedene eingehende Pakete" zu quantifizieren ... Relativ gesehen sollten Herzschläge nicht viel sein, wenn ein modernes System typischerweise Hunderte bis Tausende von Paketen pro Sekunde verarbeiten kann, abhängig von der Anzahl und Art Ihrer NICs . Ich vermute, dass Herzschläge im Bereich von Dutzenden pro Minute liegen könnten ... – twalberg

Antwort

0

Wie lange dauert es, bis Ihre Anwendung ein Paket bearbeitet? Für die Ping-Dateien ist es wahrscheinlich schneller, sie einfach so zu verarbeiten, wie sie empfangen werden. Sie können die anderen in eine gemeinsame Datenstruktur wie eine bestimmte Blockierungswarteschlange stellen. Wenn die Warteschlange leer ist, warten die Worker-Threads auf Neu Jobs, und wenn ein neuer Job hinzugefügt wird, wird ein Thread aufgeweckt und erledigt den Job.

Wenn Sie wahrscheinlich einen Thread pro Paket starten, verbrauchen Sie mehr Zeit beim Starten und Stoppen der Threads als beim eigentlichen Ausführen des Jobs.

Wenn die Dinge, die als Antwort auf ein Paket zu tun sind, nicht so zeitaufwendig für alle Arten von Paketen sind, kann es sein, dass die zusätzliche Zeit mit den Sperren der Warteschlange und dem Planen von Threads Ihr Programm langsamer macht eher als schneller.

In jedem Fall Thread-Pool verwenden und die Worker am Anfang starten. Wenn Sie möchten, können Sie die Anzahl der aktiven Threads abhängig von der Auslastung der letzten Minuten dynamisch erhöhen oder verringern.

+0

Die Zeit variiert leicht. Die meisten Pakete werden schnell bearbeitet, aber bei einigen Aktionen werden neue Pakete gesendet, die eine Antwort erwarten. Aber ich denke, ich werde mit dem Thread-Pool und der Warteschlange gehen. Vielen Dank. – Wondering

0

Ich würde eine event driven architecture verwenden. Das Erstellen eines neuen Threads für jedes Paket ist nicht skalierbar, daher funktioniert dies mit einer gewissen Arbeitslast, aber es gibt einen Punkt, an dem es nicht mehr funktioniert. Du könntest das mit z.B. ein Chat-Programm wie der Facebook-Chat, bei dem Nachrichten die Pakete sind. Eine ereignisgesteuerte Architektur wäre skalierbar und IMHO genau das, wonach Sie suchen. Einfach googeln, da Bibliotheken für viele Programmiersprachen, also wähle einfach die richtige für dich aus (ich mache das gerne in Erlang, Scala, C oder Python).

edit: ok, habe das Java-Tag nicht gesehen. Aber die Sprache spielt keine Rolle.

Werfen Sie einen Blick auf diesen Link zum Beispiel: http://www.nightmare.com/medusa/async_sockets.html

ich es ziemlich gut finde die Idee der ereignisgesteuerte Programmierung zu bekommen.

+0

Aber er benutzt UDP, also hat er wahrscheinlich nur einen Dateideskriptor. – LtWorf

+0

Das schließt die Möglichkeit nicht aus, es asynchron zu machen. Suchen Sie nach nicht-blockierenden Sockets, asynchronen E/A oder sogar ereignisgesteuerten Sockets (im Grunde beschreibt alle die gleiche Idee). – Cravid

+0

Ich weiß, dass es immer noch möglich ist, aber ich bin mir nicht sicher, ob es sich in dieser speziellen Situation lohnt. – LtWorf

Verwandte Themen