我正在尝试了解 netty 缓冲区和水印。
作为测试用例,我有一个写入客户端的网络服务器,客户端被阻塞(每次读取之间基本上有 10 秒的 hibernate )
在正常 I/O 下,如果接收方被阻塞,TCP 发送方将受到限制(由于流量控制,发送速度变慢),这里不是这种情况。发件人似乎在每次发送时都在写入和刷新数据。这些数据写在哪里? netty 的 flush() 中是否也会有流量控制? 请参阅:https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control
它正在写入操作系统或 TCP 缓冲区,netty channel 是否也有内部缓冲区?如果可以,我该如何配置?
我跟踪 bytesBeforeUnwritable 但它们似乎并没有减少
- 默认的高水位线和低水位线是什么?我没有在我的应用程序中设置任何东西。有什么方法可以改用它吗?
代码如下:
@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/tree/master/src/main/java/org/columbia/parikshan/proxy
编译和构建:
mvn 包
启动服务器
sh 脚本/Server.sh 3380
启动netty代理
sh scripts/nettyProxy.sh -l 0.0.0.0:3379 -o 127.0.0.1:3380
启动客户端
sh 脚本/Client.sh 127.0.0.1 3379
在客户端发送“hello”作为标准输入
netty 会在一段时间后阻止发送,bytesTillUnwritable 不会减少。
最佳答案
Where is this data being written? Is there going to be Flow control in the netty's flush() as well?
数据进入ChannelOutboundBuffer
。没有像tcp那样的流量控制。数据将保存在 ChannelOutboundBuffer
中,直到 tcp 的发送缓冲区中有空间为止。
Is it is being written to an OS or TCP buffer, does netty channel have an internal buffer as well? If so how can I configure it?
Netty 有 ChannelOutboundBuffer
在发送到 OS 缓冲区之前保存数据。您可以像下面这样配置它。
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 track bytesBeforeUnwritable but they do not seem to be decreasing
我写一个sample code该服务器写入被阻止的客户端
您的代理的 AUTO_READ
是错误的。 NettyProxyFrontendHandler#channelRead
只会在调用 ctx.channel().read()
( future 的监听器)时调用。监听器将在 writeAndFlush
完成后被调用。 writeAndFlush
将生成一个任务,该任务将在消息写入操作系统缓冲区时完成。如果操作系统的缓冲区已满,任务将被阻塞。 netty 的缓冲区不可能变得不可写,它始终是可写的。
What is the default High and Low Watermark? I have not set anything in my application. Is there any way to use this instead?
您可以在 DefaultChannelConfig
-> WriteBufferWaterMark.DEFAULT
中查看默认水位线。当数据在ChannelOutboundBuffer
> high water mark isWritable 返回false,< low water mark 返回true。
/**
* 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();
关于java - 了解 netty channel 缓冲区和水印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42750075/