Limitation de bande passante avec OMATPE
Question
Mon serveur Web (sur mesure sur le dessus de Netty) utilise pour faire des demandes proxies client Web (également construit sur mesure avec Netty) à S3.
Client -> Webserver|Webclient -> S3
Le but du système est de téléchargement de fichiers de tuyau directement à S3 avec un peu de logique:
-
Webserver
accepte la demande du client (POST); - Règle
Client
lisibilité du canal faux et vérifie un tas de choses; - Lorsque tout est vérifié avec succès, il utilise le
Webclient
pour se connecter àS3
; - Lorsque la
Webclient
se connecte àS3
:- il envoie un 100 Continuer au client
- il définit la lisibilité du canal
Client
true
- A partir de là, tous les morceaux reçus par le
Webserver
sont remis à laWebclient
de transmettre.
Dans le cas (très improbable) que la connexion entre Client
et Webserver
est plus rapide que la connexion entre Webclient
et S3
, je dois gaz la connexion entre Client
et Webserver
.
L'approche que j'ai été tout simplement garder un compteur d'octets reçus par le Webserver
(qui incrémente chaque Client
temps envoie des données) et qui décrémente chaque fois qu'une écriture finalise de Webclient
. Chaque fois que la quantité de données sur ce tampon passe au-dessus d'une lisibilité seuil, le canal du Client
est réglé sur false
.
Cela fonctionne très bien jusqu'à ce que j'ajouter un OrderedMemoryAwareThreadPoolExecutor
au pipeline du serveur.
Une solution simple consiste à utiliser un OioClientSocketChannelFactory
sur le Webclient
. Cela provoque les appels à Channel.write
à blocage, donc quand messageReceived()
est appelé le gestionnaire du Webserver
- et, par conséquent Channel.write
est appelée sur la Webclient
-. Arrive étranglement « naturellement »
Cependant, si j'utilise un NioClientSocketChannelFactory
sur le Webclient
, puis appelle à Channel.write
devenir asynchrone et la limitation cesse de fonctionner.
En fait ce que je remarque est que Channel.setReadability(false)
semble avoir aucun effet lorsqu'un OrderedMemoryAwareThreadPoolExecutor
est inséré dans la canalisation.
Comment puis-je effectuer étranglant à l'aide OMATPE dans le pipeline?
La solution
1) OrderedMemoryAwareThreadPoolExecutor surveille également la mémoire de canal (dans le cas de taille de données reçu) et suspendre / activer la lecture lorsque au-dessus / en dessous de la taille maximale configurée (par constructeur OrderedMemoryAwareThreadPoolExecutor).
2) Lors de son utilisation avec un ExecutionHandler, le gestionnaire pourra événements d'état rejets canal, si une pièce jointe trouve dans le cadre (mais que l'attachement de contexte est généralement fixé par OrderedMemoryAwareThreadPoolExecutor, de ne pas permettre au-dessus de gestionnaires en amont pour modifier l'état du canal et Cause OutOfMemoryException).
boolean readSuspended = ctx.getAttachment() != null;
if (readSuspended) {
// Drop the request silently if MemoryAwareThreadPool has
// set the flag.
e.getFuture().setSuccess();
return;
}
Je pense, vous devez configurer min, taille de la mémoire de canal maximum de OMATPE, ou vous pouvez avoir un conduit d'attache de contexte à cette situation?
Autres conseils
Comme dit Jestan, s'il vous plaît se référer à org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler
dans le maître. En outre, vous devrez configurer votre receiveBufferSizePredictorFactory
afin qu'il ne retourne pas de valeur trop importante. Dans le cas contraire, Netty va simplement allouer un grand tampon et le remplir très rapidement. Utilisez AdaptiveReceiveBufferSizePredictorFactory
avec une plus petite maximale en combinaison avec ChannelTrafficShapingHandler
.