You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WebSocket的modifyHandshake方法运行在工作线程?

Quarkus WebSocket modifyHandshake 阻塞IO线程问题解决

问题描述

实现ServerEndpointConfig.Configurator并重写modifyHandshake处理WebSocket握手逻辑,方法内包含阻塞代码(如Thread.sleep(3000)),但该方法始终运行在Vert.x IO线程中,触发阻塞警告。尝试配置quarkus.websocket.dispatch-to-worker=true仅对@ServerEndpoint的@OnOpen方法生效;给modifyHandshake添加@Blocking注解也无法将其切换到工作线程执行。

复现代码

public class WebSocketEndpointConfigurator extends ServerEndpointConfig.Configurator {

  @Override 
  public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
    // 阻塞代码示例
    try {
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
  }
}

报错日志

WARN [io.vertx.core.impl.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-7,5,main] has been blocked for 128597346 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked

解决方案

1. 手动将阻塞逻辑提交到工作线程

由于modifyHandshake不受@Blocking或现有配置的线程调度控制,需手动将阻塞代码委托给Quarkus工作线程池执行。使用VertxContextSupport调度任务,并通过同步等待确保握手逻辑完成:

import io.quarkus.vertx.VertxContextSupport;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class WebSocketEndpointConfigurator extends ServerEndpointConfig.Configurator {

  @Override 
  public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
    CountDownLatch latch = new CountDownLatch(1);

    VertxContextSupport.subscribeBlocking(
      () -> {
        try {
          // 执行阻塞操作
          Thread.sleep(3000);
          // 将处理结果存入config,供后续端点方法使用
          config.getUserProperties().put("handshakeData", "processed");
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        } finally {
          latch.countDown();
        }
      },
      false
    );

    try {
      // 设置超时,避免请求长时间挂起
      if (!latch.await(5, TimeUnit.SECONDS)) {
        throw new RuntimeException("Handshake processing timed out");
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new RuntimeException("Handshake interrupted", e);
    }
  }
}

2. 升级Quarkus版本(推荐)

Quarkus 2.4.1.Final为旧版本,后续LTS版本(如2.13.x及以上)优化了WebSocket Configurator的线程调度逻辑,@Blocking注解可能会对modifyHandshake生效,或提供了专门的配置项控制该方法的执行线程池。

注意事项

  • 禁止在Vert.x IO线程中执行任何阻塞操作,会严重降低应用并发处理能力。
  • 手动调度任务时需合理设置超时时间,防止握手请求长时间占用连接资源。

内容的提问来源于stack exchange,提问作者spaykit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:35:30