[英]Throttling reads on streams in HTTP/2 with Netty
In the Netty 4 proxy example AUTO_READ is turned off, which according to this answer is so that a channel sending a lot of data to the proxy doesn't use up too many buffers, which makes sense.在 Netty 4 代理示例中AUTO_READ 被关闭,根据这个答案,这是为了向代理发送大量数据的通道不会占用太多缓冲区,这是有道理的。
However, my understanding is that in HTTP/2 you should never delay reads, and instead deal with the flow control on a stream-by-stream basis.但是,我的理解是,在 HTTP/2 中,您永远不应该延迟读取,而是逐个流地处理流量控制。 I can't figure out how to do this in Netty though.
我不知道如何在 Netty 中做到这一点。
It feels like it should be achieved by returning 0 in onDataRead
on an Http2ConnectionHandler
.感觉应该通过在
onDataRead
上的Http2ConnectionHandler
返回 0 来实现。 The following contrived example is how I expected it to work, where the bytes are not consumed for 100ms:以下人为示例是我期望它的工作方式,其中 100 毫秒不消耗字节:
@Override
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data,
int padding, boolean endOfStream) throws Http2Exception {
int processed = data.readableBytes() + padding;
Http2LocalFlowController flowController = decoder().flowController();
Http2Stream stream = connection().stream(streamId);
executorService.schedule(() -> {
ctx.executor().execute(() -> {
try {
// ...do stuff...
flowController.consumeBytes(stream, processed);
} catch (Http2Exception e) {
e.printStackTrace(); // now what?
}
});
}, 100, TimeUnit.MILLISECONDS);
return 0;
}
When I use this, no exception is thrown, and the client just times out.当我使用它时,不会抛出任何异常,客户端只是超时。 (Note that if I call the
consumeBytes
call before returning from onDataRead
then it does work.) (请注意,如果我在从
onDataRead
返回之前调用consumeBytes
调用,那么它确实有效。)
With some extra logging, when reading 16k messages I can see immediately that 65535 bytes are unconsumed.通过一些额外的日志记录,在读取 16k 条消息时,我可以立即看到 65535 字节未被消耗。 After beginning to consume, a window frame is reportedly sent after 32k.
开始消费后,据报道在32k后发送一个窗口框架。 After the 4th message,
flowController.unconsumedBytes(stream)
reports 0 bytes unconsumed, however the next message never comes to onDataRead
.在第 4 条消息之后,
flowController.unconsumedBytes(stream)
报告 0 字节未使用,但是下一条消息永远不会出现在onDataRead
。
This apparently works for other people so I'm struggling to see where the issue is.这显然适用于其他人,所以我正在努力找出问题所在。
The consumeBytes
method returns a boolean that indicates whether or not a threshold was reached meaning a window update can be sent for the stream (ie to say that the stream can send more data). consumeBytes
方法返回一个布尔值,指示是否达到阈值意味着可以为流发送窗口更新(即说流可以发送更多数据)。
The method does a ctx.write
with the window update frame, but doesn't flush it.该方法对窗口更新框架执行
ctx.write
,但不刷新它。 So if nothing is flushing the context, you need to do that:因此,如果没有任何内容刷新上下文,您需要这样做:
if (flowController.consumeBytes(stream, processed)) {
ctx.flush();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.