了解Netty通道缓冲区和水印



我试图了解网络缓冲区和水印。

作为测试用例,我有一个网络服务器,它写信给客户端,客户被阻止(本质上的睡眠在每个读取之间为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();