当前位置: 首页 > 知识库问答 >
问题:

Netty服务器-TCP上的慢速消费者

农波涛
2023-03-14

我正在用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();

这就是< code>SO_BACKLOG选项的作用吗?它说它是用于正在排队的连接,但是我对正在为特定连接排队的数据包感兴趣。

共有3个答案

齐胜涝
2023-03-14

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

if (ctx.channel().isWritable()) {
    ctx.writeAndFlush(msg);
}
阮华美
2023-03-14

这就是SO_BACKLOG选项的作用吗?

这就是SO_BACKLOG选项的作用吗?

上面说是用来连接排队的

对的

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

所以你对SO_BACKLOG不感兴趣。

能业
2023-03-14

执行此操作的一种方法是使用“写入缓冲区水印”。引用爪哇语:

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

在您的子通道配置上设置适当的水印,慢速消费者将在“长”时间内标记通道不可写,而不是快速消费者。因此,侦听通道可写状态的变化并跟踪通道不可写的时间量应该可以识别慢速消费者和积压的相对严重程度,然后如果客户端的迟钝达到某个阈值,您可以断开客户端。

 类似资料:
  • 在探索和实现Proact设计模式后,遇到了一个问题,即客户端(“C”客户端)连接在限制后不再接受。开始探索netty。这是我试图做的1。C客户端建立连接2。Java服务器接受连接并开始使用TCP向客户端发送8 Mb大小的字节缓冲区。有什么想法吗?netty是一个好的选择吗?我浏览了netty的一个很好的例子,不幸的是不走运。 先谢谢你。 尊敬的Ravi

  • 我正在使用最新版本的骆驼和Netty与Spring,并且具有以下定义: 我定义了一个类来处理传入的tcp请求: 我的问题是,不管传入消息的大小,buf变量永远不会超过1024字节,因此我的请求被截断。 根据组件定义,receiveBufferSize应该是65536字节。我如何处理大的请求?

  • ?> Swoole\Coroutine\Server 是一个完全协程化的类,用于创建协程TCP服务器,支持TCP和unixSocket类型。 与Server模块不同之处: 动态创建销毁,在运行时可以动态监听端口,也可以动态关闭服务器 处理连接的过程是完全同步的,程序可以顺序处理Connect、Receive、Close事件 !> 在4.4以上版本中可用 短命名 可使用Co\Server短名。 方法

  • 程序代码 server.php //创建Server对象,监听 127.0.0.1:9501端口 $serv = new Swoole\Server("127.0.0.1", 9501); //监听连接进入事件 $serv->on('Connect', function ($serv, $fd) { echo "Client: Connect.\n"; }); //监听数据接收事

  • Swoole\Network\Server 使用swoole扩展作为底层驱动 Swoole\Network\SelectTCP 使用PHP提供的stream_select作为事件驱动方式 Swoole\Network\BlockTCP 阻塞方式的TCP Swoole\Network\EventTCP libevent扩展作为底层驱动

  • 问题内容: 这实际上是我在这里的第一篇文章,一段时间以来我一直在试图弄清楚这一点,但是我终于打电话给该旗帜,并将尝试寻求有关此主题的一些帮助。 因此,我有一个客户端和一个服务器,它们是根据回显客户端/服务器和安全聊天客户端/服务器建模的。我对聊天的SSL部分和使用回显仅对确保我在客户端/服务器之间收到响应不感兴趣。我将在这篇文章的底部添加所有相关代码。我现在遇到的问题是,在客户端连接后,我可以从服