我试图了解网络缓冲区和水印。
作为测试用例,我有一个网络服务器,它写信给客户端,客户被阻止(本质上的睡眠在每个读取之间为10秒)
-
在正常的I/O TCP下,将会限制(由于流量控制,发送速度放慢速度),如果接收器被阻塞,则在这里不是这种情况。发件人似乎在每次发送上都保持写作和冲洗数据。这些数据在哪里写?Netty的Flush()也会有流量控制吗?请参阅:https://en.wikipedia.org/wiki/transmission_control_protocol#flow_control
-
是将其写入OS或TCP缓冲区,Netty通道也有内部缓冲区吗?如果是这样,我该如何配置?
-
i跟踪bytesbeforeuntable,但它们似乎并没有减少
- 默认高和低水印是什么?我没有在应用程序中设置任何东西。有什么办法可以使用它吗?
代码下面:
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
if (server2OutboundChannel.isActive()) {
if(server2OutboundChannel.isWritable()) {
server2OutboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) {
// was able to flush out data, start to read the next chunk
//System.out.println(server2OutboundChannel.bytesBeforeUnwritable());
ctx.channel().read();
} else {
future.channel().close();
}
}
});
}else{
System.out.println("Channel is no longer writeable");
System.out.println(server2OutboundChannel.bytesBeforeUnwritable());
System.out.println(server2OutboundChannel.bytesBeforeWritable());
}
}
}
使用端到端源代码重新创建的详细步骤:
克隆https://github.com/nipunarora/nettyduplicator。
具体来说,代理代码在这里:
https://github.com/nipunarora/nettyDuplicator/tree/master/src/main/java/org/columbia/parikshan/proxy
编译和构建:
mvn package
启动服务器
sh scripts/Server.sh 3380
启动Netty代理
sh scripts/nettyProxy.sh -l 0.0.0.0:3379 -o 127.0.0.1:3380
启动客户端
sh scripts/Client.sh 127.0.0.1 3379
客户端中的std输入发送
一段时间后发送的Netty块,而bytestillunbritable不会减少。
这些数据在哪里写?Netty的Flush()也将有流量控制吗?
数据用于ChannelOutboundBuffer
。没有像TCP这样的流控制。数据将保存在ChannelOutboundBuffer
中,直到TCP的发送缓冲区中有空间。
是被写入OS或TCP缓冲区,Netty通道也有内部缓冲区吗?如果是这样,我该如何配置?
Netty具有ChannelOutboundBuffer
,可以在发送到OS'Buffer之前保留数据。您可以像下面一样配置它。
Bootstrap bootstrap = new Bootstrap();
bootstrap.option(ChannelOption.SO_RCVBUF, soRcvBufSize);
bootstrap.option(ChannelOption.SO_SNDBUF, soSndBufSize);
bootstrap.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, writeBufferHighWaterMark);
i跟踪bytesbeforeunablebleditable,但它们似乎并没有减少
我编写了服务器写入阻止的客户端
的示例代码您的代理人的AUTO_READ
是错误的。仅当调用ctx.channel().read()
(将来听众)时,NettyProxyFrontendHandler#channelRead
才会被调用。writeAndFlush
完成后,将调用侦听器。writeAndFlush
将生成一个任务,并且当MSG写入OS的缓冲区时,任务将完成。如果OS的缓冲区被填充,则该任务将被阻止。Netty的缓冲区不会变得不可创造,它总是可以写的。
默认高和低水印是什么?我没有在应用程序中设置任何东西。有什么办法可以使用它吗?
您可以检查DefaultChannelConfig
-> WriteBufferWaterMark.DEFAULT
中的错误水印。当ChannelOutboundBuffer
中的数据>高水标记为frats false false<低水标记返回真实。
/**
* Returns {@code true} if and only if the I/O thread will perform the
* requested write operation immediately. Any write requests made when
* this method returns {@code false} are queued until the I/O thread is
* ready to process the queued write requests.
*/
boolean isWritable();