2017-06-15 2 views
1

In den Versionen von Netty vor 4 (3.x) gab es eine Möglichkeit, die Kanalverwaltung über einen Executor speicherfähig zu machen und mit dem OrderedMemoryAwareThreadPoolExecutor Executor die Aktionen auszuführen ein gegebenes Channel. Diese OrderedMemoryAwareThreadPoolExecutor in 3.x würde kümmern sich um die Anordnung der Ereignisbehandlung für einen Kanal, obwohl sie von verschiedenen Threads ausgeführt werden könnte, sowie für die Einschränkung der Gesamtspeicher von Channel verwendet werden. Wenn der Kanalspeicher (aufgrund der Ereignisse in der Warteschlange) einen bestimmten Schwellenwert überschreitet, wird die Ausführung von Ereignissen blockiert, bis der Speicher freigegeben ist.Speicherbewusste Kanalbehandlung mit Netty 4.1

In 4.x gibt es jedoch keinen solchen Mechanismus. Das neue Thread-Modell sieht die Reihenfolge der ausgeführten Ereignisse vor (da Ereignisse für einen bestimmten Kanal von einem einzelnen Thread ausgeführt werden), aber es scheint keine Möglichkeit zu geben, den von einem einzelnen Channel in einem der EventExecutorGroup s verbrauchten Speicher einzuschränken. Was das bedeutet ist, dass, wenn das nicht möglich ist, viele Ereignisse, die an einen bestimmten Channel gesendet werden, den Speicher auf dem Server erschöpfen könnten. Obwohl ich dies noch nicht getestet habe, dachte ich, dass es sich lohnen könnte, hier zu fragen, ob das bei Netty 4.x tatsächlich der Fall ist.

So im Wesentlichen meine Frage ist:

Gibt es eine Möglichkeit, den Speicher durch einen einzelnen Channel verbraucht zu beschränken, wenn eine EventExecutorGroup mit einem ChannelHandler in Netty 4.x verwenden?

Antwort

2

Sie haben Recht. Diese Art der Situation ist möglich.

Allerdings hat Netty ChannelOption.WRITE_BUFFER_WATER_MARK Option für Ihren Kanal. Wenn Sie also zu schnell in einen Kanal schreiben und eine Warteschlange mit ausstehenden Nachrichten überschreitet, wird der Kanal ChannelOption.WRITE_BUFFER_WATER_MARK, auf den Sie schreiben, nicht beschreibbar. So können Sie Ihren Code wache mit:

if (channel.isWritable()) { 
} 

oder

if (ctx.channel().isWritable()) { 
} 

Und so anstrengend des Speichers zu verhindern, wenn der Kanal belegt ist oder verbraucht langsam Ereignisse.

Sie können auch ChannelOption.AUTO_READ für Kanal ändern, die Ereignisse und behandelt dies manuell mit erzeugt:

ctx.channel().config().setAutoRead(false); 

So Ihrem Server aus dem Kanalereignis lesen stoppen, die sie zu viel erzeugt. Here is pull request, die auf diese Weise zeigt.

+0

Das macht Sinn. Danke Dmitriy! – gravetii