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:
    1. il envoie un 100 Continuer au client
    2. il définit la lisibilité du canal Client true
  • A partir de là, tous les morceaux reçus par le Webserver sont remis à la Webclient 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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top