使用OMATPE进行带宽限制

时间:2011-12-04 13:13:34

标签: java netty

我的网络服务器(自定义构建在Netty之上)使用Web客户端(也是使用Netty自定义)来向S3发出代理请求。

Client -> Webserver|Webclient -> S3

系统的目的是通过一些逻辑将文件直接上传到S3:

  • Webserver接受客户请求(POST);
  • Client频道可读性设置为false并验证一堆内容;
  • 成功验证所有内容后,会使用Webclient连接到S3;
  • Webclient连接到S3时:
    1. 它将100-Continue发送回客户端
    2. 它将Client频道可读性设置为true
  • 从那时起,Webserver收到的所有块都会移交给Webclient转发。

ClientWebserver之间的连接比WebclientS3之间的连接速度快的(极不可能)事件中,我需要限制连接ClientWebserver

我采用的方法只是保留Webserver收到的字节计数器(每次Client发送数据时递增),每次写Webclient完成时递减。只要此缓冲区上的数据量超过给定阈值,Client的通道可读性就会设置为false

在我向服务器的管道添加OrderedMemoryAwareThreadPoolExecutor之前,这很有效。

一个简单的解决方案是在OioClientSocketChannelFactory上使用Webclient。这会导致对Channel.write的调用被阻止,因此在messageReceived()的处理程序上调用Webserver时,Channel.write会调用Webclient - 节流“自然地”发生。

但是,如果我在NioClientSocketChannelFactory上使用Webclient,则对Channel.write的调用将变为异步,并且限制将停止工作。

基本上我在这里注意到,当Channel.setReadability(false)插入管道时OrderedMemoryAwareThreadPoolExecutor似乎没有效果。

如何在管道中使用OMATPE执行限制?

2 个答案:

答案 0 :(得分:2)

1)OrderedMemoryAwareThreadPoolExecutor还监视通道内存(在您的情况下接收数据大小)并在高于/低于配置的最大大小(通过OrderedMemoryAwareThreadPoolExecutor构造函数)时暂停/启用读取。

2)当它与ExecutionHandler一起使用时,处理程序可能会丢弃通道状态事件,如果在上下文中找到某些附件(但该上下文附件通常由OrderedMemoryAwareThreadPoolExecutor设置,不允许上面的上游处理程序更改通道状态和导致OutofMemoryException)。

            boolean readSuspended = ctx.getAttachment() != null;
            if (readSuspended) {
                // Drop the request silently if MemoryAwareThreadPool has
                // set the flag.
                e.getFuture().setSuccess();
                return;
            }

我认为,您必须配置OMATPE的最小,最大通道内存大小,或者您可能有上下文附件导致这种情况?

答案 1 :(得分:2)

正如杰斯坦所说,请参考主人的org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler。此外,您必须配置receiveBufferSizePredictorFactory,以便它不会返回太大的值。否则,Netty将只分配一个大缓冲区并快速填充它。使用AdaptiveReceiveBufferSizePredictorFactory最小值与ChannelTrafficShapingHandler组合使用。