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

监控Netty事件循环队列的大小

李泓
2023-03-14

我们已经实现了对Netty事件循环队列的监控,以便了解我们的一些Netty模块的问题。监视器使用io.netty.util.concurrent.单线线程事件执行器#挂起任务方法,该方法适用于大多数模块,但对于每秒处理几千个HTTP请求的模块,它似乎被挂起,或者非常慢。我现在意识到文档严格指定这可能是一个问题,我觉得很差劲…所以我正在寻找另一种方法来实现这个监视器。

您可以在此处看到旧代码:https://github.com/outbrain/ob1k/blob/6364187b30cab5b79d64835131d9168c754f3c09/ob1k-core/src/main/java/com/outbrain/ob1k/common/metrics/NettyQueuesGaugeBuilder.java

  public static void registerQueueGauges(final MetricFactory factory, final EventLoopGroup elg, final String componentName) {

    int index = 0;
    for (final EventExecutor eventExecutor : elg) {
      if (eventExecutor instanceof SingleThreadEventExecutor) {
        final SingleThreadEventExecutor singleExecutor = (SingleThreadEventExecutor) eventExecutor;
        factory.registerGauge("EventLoopGroup-" + componentName, "EventLoop-" + index, new Gauge<Integer>() {
          @Override
          public Integer getValue() {
            return singleExecutor.pendingTasks();
          }
        });

        index++;
      }
    }
  }

我的问题是,有没有更好的方法来监控队列大小?

这可能是一个非常有用的度量,因为它可以用于了解延迟,并且在某些情况下也可以用于应用背压。

共有2个答案

公冶安怡
2023-03-14

现在,在2021年,Netty在内部使用JCTools队列并且< code>pendingTasks()执行非常快(几乎总是常数时间),所以即使than javadoc仍然声明这个操作很慢,您也可以毫无顾虑地使用它。以前的问题是对队列中的元素进行计数是一个线性操作,但是在迁移到JCTools库之后,这个问题就消失了。

令狐翰
2023-03-14

您可能需要将更改跟踪为从单线程事件执行器实例中添加和删除的任务。

为此,您可以创建一个包装和/或扩展单线程事件执行器的类。然后你会有一个java.util.concurrent.atomic.原子整数器,每次添加新任务时,你会调用增量和获取(),每次删除/完成一个任务时,你会调用decrementAndget()

然后,AtomicInteger会给出当前未完成任务的数量。您可能会重写< code>pendingTasks()来使用该值(不过要小心——我不是100%肯定不会有副作用)。

这会给正在执行的每个任务增加一点开销,但会使检索未决任务的数量接近恒定速度。

当然,这样做的缺点是它比你目前所做的更具侵入性,因为你需要配置你的应用程序以使用不同的事件执行器。

铌。这只是关于如何解决此问题的建议 - 我没有专门对 Netty 执行此操作。虽然我过去用其他代码做过这种事情。

 类似资料:
  • 问题内容: 如果我没记错的话,我记得异步I / O的“事件循环”模型(Node.js,Nginx)不适合用于提供大文件。 是这种情况,如果是,周围是否有方法?我正在考虑在Node中编写一个实时文件浏览器/文件服务器,但是文件的大小可能在100MB到3GB之间。我认为事件循环将一直阻塞直到文件被完全提供为止? 问题答案: 不,它不会被阻止。node.js将分块读取文件,然后将那些块发送到客户端。在大

  • 请说明当netty server和netty client连接成代理时,请求、线程、eventloop、服务器通道和客户端通道之间的关系。在开始之前,我认为对于每个请求,netty服务器都会从获取一个工作线程,以及一个(绑定到工作线程,使用线程池中有限的对象ID)来处理该入站消息,并将其发送到来自netty客户端的出站。此后,可能的服务器<代码>频道受到限制,而客户端<代码>频道受到限制(因为出站

  • 假设我有一个大小为[10]的数组,当该数组被填满时,我想实现一个FIFO结构,而不是它只是填满了,因此无法向数组中添加新的东西,并抛出旧的东西。 例如,如果我有一个包含汽车制造商的字符串数组,当我的数组中有10个制造商时,我希望删除最旧的条目,添加最新的条目,但要考虑kepping FIFO。我如何在这样的方法中实现它:

  • 介绍 Horizon 提供了一个漂亮的仪表盘,并且可以通过代码配置你的 Laravel Redis 队列,同时能够让你轻松地监控你的队列系统中诸如任务吞吐量,运行时间和失败任务等关键指标。 所有配置项都存放在一个简单的配置文件中,应当把它放进团队能够协同维护的版本控制中。 安装 {note} 由于 Horizon 中用了异步处理信号,所以安装扩展包需要 PHP 环境在 7.1 以上。 你应该用 C

  • 我们有一个分布式应用程序,它使用Netty (4)进行底层通信。系统中进程执行多个任务。每个任务包含一组输入和输出通道。在Netty中,通道被永久分配给单个EventLoop。在(Nio)EventLoopGroup中,通道到EventLoop的映射以循环方式进行。我们希望对这种映射有更多的控制,并将同一任务的所有通道分配给相同的EventLoop。这种“Channel-EventLoop aff

  • 顶点似乎只由单个线程执行,并且总是由同一个线程执行。但是Vert. x能够通过每个CPU创建一个线程来使用机器中的所有CPU。每个线程可以向多个顶点发送消息。 但在性能测试期间,在标准verticle上评测Vertex http服务器时,我只能看到一个线程处理所有处理(vert.x-eventloop-thread-0)。 我该怎么做才能让我的8个事件循环线程都处理到verticle的消息?