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?
Leistung und Skalierbarkeit. Viel weniger Threads, und es sollte unser Design vereinfachen. –
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. –