为什么即使具有阻塞属性,Vertx 也会抛出警告?

Why does Vertx throws a warning even with blocking attribute?

我有一个使用事件总线的 Quarkus 应用程序。

有问题的代码如下所示:

    @ConsumeEvent(value = "execution-request", blocking = true)
    @Transactional
    @TransactionConfiguration(timeout = 3600)
    public void consume(final Message<ExecutionRequest> msg) {
        try {
            execute(...);
        } catch (final Exception e) {
            // some logging
        }
    }

    private void execute(...)
            throws InterruptedException {
        // it actually runs a long running task, but for 
        // this example this has the same effect
        Thread.sleep(65000);
    }

为什么我还是得到一个

WARN  [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-worker-thread-0,5,main] has been blocked for 63066 ms, time limit is 60000 ms: io.vertx.core.VertxException: Thread blocked

我是不是做错了什么? ConsumeEvent 注释中的阻塞参数是否不足以让该句柄在单独的 Worker 中处理?

您的注释按设计工作;该方法在工作线程中为 运行。您可以通过线程名称“vert.x-worker-thread-0”和记录警告之前的 60 秒超时来判断。我相信 eventloop 线程只有 3 秒超时。

默认的 Vert.x 工作线程池不是为“非常”长的 运行 阻塞代码设计的,如 their docs:

中所述

Warning:

Blocking code should block for a reasonable amount of time (i.e no more than a few seconds). Long blocking operations or polling operations (i.e a thread that spin in a loop polling events in a blocking fashion) are precluded. When the blocking operation lasts more than the 10 seconds, a message will be printed on the console by the blocked thread checker. Long blocking operations should use a dedicated thread managed by the application, which can interact with verticles using the event-bus or runOnContext

该消息提到阻塞超过 10 秒会触发警告,但我认为这是一个错字;默认值实际上是 60。

为避免警告,您需要创建一个专用的 WorkerExecutor(通过 vertx.createSharedWorkerExecutor)并配置了非常高的 maxExcecuteTime。但是,您似乎无法告诉 @ConsumeEvent 注释使用它而不是默认工作池,因此您还需要手动创建一个事件总线使用者,或者使用常规 @ConsumeEvent 注释,但在其中调用 workerExectur.executeBlocking