Netty服务器 - 通过TCP减慢消费者

时间:2017-02-08 20:55:16

标签: java tcp netty

我正在使用Netty v4编写TCP服务器。服务器将处理来自客户端的多个连接,并将数据流传输给它们。

我希望能够检测客户端何时以慢速消耗数据。我基本上想避免TCP缓冲区变满,因为客户端很慢!

这基本上是ZeroMQ所做的(称为“慢速用户检测(自杀蜗牛模式)”)。如何使用Netty完成?

我目前的代码是(我只是展示服务器设置):

      ServerBootstrap b = new ServerBootstrap();
      b.group(bossGroup, workerGroup)
          .channel(NioServerSocketChannel.class)
          .option(ChannelOption.SO_BACKLOG, 1000)
          .handler(new LoggingHandler(LogLevel.INFO))
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
              ChannelPipeline p = ch.pipeline();
              p.addLast(new Handler());
            }
          });

      ChannelFuture f = b.bind(8000).sync();
      f.channel().closeFuture().sync();

那是SO_BACKLOG选项吗?它说连接正在排队,但我对排队等待特定连接的数据包感兴趣。

3 个答案:

答案 0 :(得分:0)

  

这是SO_BACKLOG选项的作用吗?

SO_BACKLOG选项的作用是什么?

  

它表示连接排队

正确。

  

但我对排队等待特定连接的数据包感兴趣

所以你对SO_BACKLOG并不感兴趣。

答案 1 :(得分:0)

您可以这样做的一种方法是使用WriteBufferWaterMark。引用javadoc:

  

WriteBufferWaterMark用于设置低水位线和高水位线   用于写缓冲区。如果在写入时排队的字节数   缓冲区超过高水位线,Channel.isWritable()将开始   返回false。如果在写缓冲区中排队的字节数   超过高水位,然后下降到低水位以下   mark,Channel.isWritable()将再次开始返回true。

在您的子频道configs上设置适当的水印,一个缓慢的消费者会将频道标记为“漫长”的时间段与不太活跃的消费者不可写。因此,监听通道可写性状态的变化并跟踪通道不可写的时间量应该识别缓慢的消费者和积压的相对严重性,然后如果客户端的迟缓达到某个阈值就可以断开连接。

答案 2 :(得分:0)

如果您的唯一目标是避免缓冲区溢出(背压),这种方法就足够了:

if (ctx.channel().isWritable()) {
    ctx.writeAndFlush(msg);
}