Frage
Mein Webserver (benutzerdefiniert auf Netty integriert) verwendet einen Web -Client (auch benutzerdefiniert mit Netty erstellt), um Proxied -Anforderungen an S3 zu stellen.
Client -> Webserver|Webclient -> S3
Der Zweck des Systems besteht darin, die Datei -Uplope direkt mit ein wenig Logik auf S3 zu laden:
Webserver
Akzeptiert die Kundenanforderung (Post);- Sets
Client
Kanallesbarkeit zu falsch und überprüft ein paar Dinge; - Wenn alles erfolgreich überprüft wird, verwendet es die
Webclient
zu verbinden mitS3
; - Wenn der
Webclient
verbindet sich mitS3
:- Es sendet einen 100-kontinuierlichen Rückgang an den Client
- Es setzt
Client
Kanallesbarkeit zu wahr
- Von da an erhalten alle Brocken von der erhalten
Webserver
werden an die übergebenWebclient
weiterleiten.
In dem (höchst unwahrscheinlichen) Ereignis, dem die Verbindung zwischen Client
und Webserver
ist schneller als die Verbindung zwischen Webclient
und S3
, Ich muss die Verbindung zwischen dem Zusammenhang zwischen drosseln Client
und Webserver
.
Der Ansatz, den ich verfolgte, war einfach einen Zähler von Bytes, die von der erhalten wurden Webserver
(Welche Schritte jedes Mal Client
sendet Daten) und das verringert sich jedes Mal, wenn ein Schreiben von geschrieben wird Webclient
vervollständigt. Immer wenn die Datenmenge zu diesem Puffer über einen bestimmten Schwellenwert geht, ist die Client
Die Kanal -Lesbarkeit ist auf false
.
Das funktioniert großartig, bis ich eine hinzufüge OrderedMemoryAwareThreadPoolExecutor
zur Pipeline des Servers.
Eine einfache Lösung besteht darin, eine zu verwenden OioClientSocketChannelFactory
auf der Webclient
. Dies verursacht die Anrufe an Channel.write
blockieren, also wann messageReceived()
wird auf die aufgerufen Webserver
Handler - und folglich Channel.write
wird auf die aufgerufen Webclient
- Droseln passiert "natürlich".
Wenn ich jedoch a benutze NioClientSocketChannelFactory
auf der Webclient
, ruft dann an Channel.write
Asynchrone und Drosselungsstörungen arbeiten.
Grundsätzlich merke ich hier das Channel.setReadability(false)
scheint keine Wirkung zu tragen, wenn eine OrderedMemoryAwareThreadPoolExecutor
wird in die Pipeline eingeführt.
Wie kann ich mit Omatpe in der Pipeline Drossel durchführen?
Lösung
1) OrderedMemoryAwarethreadpoolexecutor überwacht auch den Kanalspeicher (in Ihrem Fall empfangene Datengröße) und das Lesen auszusetzen/zu aktivieren, wenn er oben/unterhalb der konfigurierten Maximalgröße (über OrderedMeMoryAwaretheadpoolexecutor -Konstruktor)).
2) Wenn es mit einem ExecutionHandler verwendet wird, kann der Handler Kanalzustandsereignisse verwirrt, wenn ein im Kontext gefundener Anhang (aber dieser Kontextanhang wird normalerweise durch geordnete MemoryAwarethreadpoolexecutor festgelegt, um nicht übersteuere Handler zu ermöglichen, den Kanalzustand zu ändern und die OutofMemoryException zu veranlassen)). .
boolean readSuspended = ctx.getAttachment() != null;
if (readSuspended) {
// Drop the request silently if MemoryAwareThreadPool has
// set the flag.
e.getFuture().setSuccess();
return;
}
Ich denke, Sie müssen Min, MAX -Kanalspeichergröße von Omatpe konfigurieren, oder Sie haben möglicherweise einen Kontextanhang, der zu dieser Situation führt?
Andere Tipps
Wie Jestan sagte, beziehen Sie sich bitte auf org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler
im Meister. Außerdem müssen Sie Ihre konfigurieren receiveBufferSizePredictorFactory
so dass es keinen zu großen Wert zurückgibt. Andernfalls wird Netty nur einen großen Puffer bereitstellen und ihn sehr schnell füllen. Verwenden AdaptiveReceiveBufferSizePredictorFactory
mit einem kleineren Maximum in Kombination mit ChannelTrafficShapingHandler
.