在 Quarkus Websocket 中阻塞 IO 线程

3
我有一个websocket接收数据,并且我想对这些数据进行一些数据库操作。以下是我的代码简化版:
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/my_socket")
@ApplicationScoped
public class MySocket {

  @Inject
  Event<MySocketMessage> messageEvent;

  @OnMessage
  public void onMessage(String message) {
    messageEvent.fire(new MySocketMessage(message));
  }
}

public class MySocketMessage {

  private final String message;

  public MySocketMessage(String message) {
    this.message = message;
  }

  public String getMessage() {
    return this.message;
  }
}

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.persistence.EntityManager;

@ApplicationScoped
public class MyDatabaseHandler {

  @Inject
  EntityManager entityManager;

  public void handleMessage(@Observes MySocketMessage message) {
    // Do some blocking database operations
    Object entity = new Object(message.getMessage());
    entityManager.persist(entity);
  }
}

在单元测试中执行此代码没有问题。但是当我运行应用程序时,会出现以下异常:
2021-07-27 15:35:14,667 ERROR [ch.scs.mbv.veg.web.ScannerSocket] (vert.x-eventloop-thread-7) The my socket encountered the following error: : java.lang.IllegalStateException: You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking EntityManager operations make sure you are doing it from a worker thread.
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.checkBlocking(TransactionScopedSession.java:110)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.persist(TransactionScopedSession.java:134)
        at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.persist(ForwardingSession.java:53)
        at
...

我知道在IO线程上执行阻塞操作是不合适的,但我不关心程序的性能,因为它只会有一个用户。这也是我没有(也不想)将其变成响应式的原因。快速搜索显示,一个非常类似的问题已经在这里得到了回答:blocking EntityManager operations
因此,我尝试在代码中多个位置放置@Blocking注释,但那并没有任何效果,异常仍然弹出。我错过了什么?非常感谢您的帮助!
1个回答

7

经过大量搜索,我发现这是Quarkus版本1.13.3的一个错误导致了这个问题。我没有找到使用这个版本解决问题的方法。但是,切换到版本2.1.2解决了这个问题!

除了切换到更新的版本之外,我还必须在文件application.properties中添加以下两行:

quarkus.websocket.dispatch-to-worker=true
quarkus.quartz.start-mode=forced

如果在项目中使用了Quartz,则第二行是必需的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接