我的网络服务器(自定义构建在Netty之上)使用Web客户端(也是使用Netty自定义)来向S3发出代理请求。
Client -> Webserver|Webclient -> S3
系统的目的是通过一些逻辑将文件直接上传到S3:
Webserver
接受客户请求(POST); Client
频道可读性设置为false并验证一堆内容; Webclient
连接到S3
; Webclient
连接到S3
时:
Client
频道可读性设置为true Webserver
收到的所有块都会移交给Webclient
转发。在Client
和Webserver
之间的连接比Webclient
和S3
之间的连接速度快的(极不可能)事件中,我需要限制连接Client
和Webserver
。
我采用的方法只是保留Webserver
收到的字节计数器(每次Client
发送数据时递增),每次写Webclient
完成时递减。只要此缓冲区上的数据量超过给定阈值,Client
的通道可读性就会设置为false
。
在我向服务器的管道添加OrderedMemoryAwareThreadPoolExecutor
之前,这很有效。
一个简单的解决方案是在OioClientSocketChannelFactory
上使用Webclient
。这会导致对Channel.write
的调用被阻止,因此在messageReceived()
的处理程序上调用Webserver
时,Channel.write
会调用Webclient
- 节流“自然地”发生。
但是,如果我在NioClientSocketChannelFactory
上使用Webclient
,则对Channel.write
的调用将变为异步,并且限制将停止工作。
基本上我在这里注意到,当Channel.setReadability(false)
插入管道时OrderedMemoryAwareThreadPoolExecutor
似乎没有效果。
如何在管道中使用OMATPE执行限制?
答案 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
组合使用。