2009-09-21 13 views
6

Ich bin gerade dabei, unseren Java-Code in NIO umzuwandeln, aber ich bin mir nicht sicher, wie ich ihn am besten gestalten könnte.Bestes Modell für eine NIO-Implementierung?

Mein erster Ansatz war, einen Pool von Selektor-Threads zu erstellen. Die Threads werden nach Bedarf gestartet/gelöscht, und Kanäle werden in einem Selektor-Thread registriert, wenn sie auf Round-Robin-Art verbunden/akzeptiert werden. Von dort blockiert jeder Thread bei select(), und wenn er aufgewacht ist, wird der entsprechende Rückruf ausgeführt, der jedem Kanal zugeordnet ist, der einen ausgewählten Schlüssel hat.

Zusätzlich zu diesem "Multiple Selector Thread" -Design, habe ich auch gesehen, dass Leute sagen, einen einzelnen Selektor-Thread zu verwenden, und einen Pool von Dispatch-Threads. Wenn eine IO-Operation ausgeführt werden kann, benachrichtigt der Selektor einen Dispatcher-Thread, der die Anforderung verarbeitet. Dieses Modell hat den Vorteil, den IO-Thread nicht zu blockieren, aber jetzt zwingen wir alle IO in einen einzigen Thread und befassen sich mit der Synchronisation/einer Ereigniswarteschlange im Dispatcher.

Zusätzlich wäre ich nicht in der Lage, einen einzelnen direkten Byte-Puffer für das Lesen jedes Kanals zu verwenden und es direkt in den Rückruf zu übergeben. Stattdessen müsste ich die Daten jedes Mal kopieren, wenn ein Lesevorgang in einem Array stattfindet und zurückgesetzt werden. (Ich denke ..)

Was ist der beste Weg, dies zu implementieren?

Antwort

4

Werfen Sie einen Blick auf die Reactor

http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

Wie Sie Ihre Wähler wollen, hängt von Ihrem usecase wirklich zu arbeiten. (Anzahl der Verbindungen, Nachrichtengröße usw.)

Was ist das Problem, das Sie lösen möchten, indem Sie von IO zu NIO konvertieren?

+0

Leistung und Skalierbarkeit. Viel weniger Threads, und es sollte unser Design vereinfachen. –

+0

Das Reaktor-Muster ist eine sehr gute Wahl. Es gibt einige Implementierungen dieses Entwurfs, die mehrere Threads für die Verarbeitung der E/A-Ereignisse verwenden. Diese Designs sind schlecht und besiegen den Zweck der nicht blockierenden asynchronen I/O. Wenn Sie ein Design für leistungsstarke und skalierbare Server schreiben, möchten Sie asynchrone I/O-Aufrufe verwenden und alles auf einem Thread speichern - dem 'Selector'-Thread. –

3

Sie wirklich suchen in Mina sollte,

http://mina.apache.org/

Es löst alle Probleme, die Sie erwähnt.

+1

Ja, obwohl es eine gute Idee ist zu versuchen zu verstehen, was unter den Abdeckungen vor sich geht. – pjp

+1

Genau das habe ich getan. Ich habe Mina nicht wirklich in meinem Projekt verwendet, aber ich habe viel vom Lesen ihrer Implementierung gelernt. –

1

Werfen Sie auch einen Blick auf netty, die wirklich schnell und funktionsreich ist und auch in großen Systemen und von großen Unternehmen wie Redhat (jboss), Twitter, Facebook ... verwendet wird.