使用Quarkus启动工作线程的正确方法是什么?

9

我正在实现一个Quarkus服务器,服务器启动时应该启动一个(无休止的)后台进程。

我知道可以通过实现@ApplicationScopedbean并实现void onStart(@Observes StartupEvent ev)方法来观察启动事件。

但是,启动后台进程的最佳方式是什么?有限制吗? 在J2EE中,不应创建线程,而应使用ManagedExecutorService或带有@Asynchronous注释的EJB。

在Quarkus中是否有类似的东西?我只找到了调度器注释(它们很好,但我只想在开始时启动一次进程)。

那么,我能否只创建线程?还是将我的无限代码放入void onStart(@Observes StartupEvent ev) 中?

谢谢


回答了这个老问题,因为它还没有得到适当的答案,但是有很多浏览量。我想你已经解决了你的问题... :) - Vinicius
2个回答

5
在EJB中,您不应该使用后台进程进行此类操作。这些“框架之外”控制的进程大部分时间都会引起非常烦人的问题。
答案是:这取决于您想在该作业中执行什么任务。
如果您想定期执行任务,则可以使用计时器。
如果您想将其用作异步工作者,则可以使用消息队列。
两者都最容易通过vert.x integration整合到Quarkus中完成。
使用@ConsumeEvent创建队列,使用
@Inject
EventBus bus;

bus.send("Example message");

发送消息。

使用@Scheduled处理定期工作,例如此示例中的操作。

如果您需要永久侦听某个套接字或文件,则会变得更加困难。也许websockets在这种情况下会有所帮助。


3

开始一个worker线程最简单的方式是使用Vertx#executeBlocking方法,如下所示:

@Inject
Vertx vertx;

void foo() {
    vertx.<String>executeBlocking(promise -> {
        // This code will be executed in a worker thread
        System.out.println("Thread: " + Thread.currentThread());
        promise.complete("Done");
    }, asyncResult -> {
        System.out.println(asyncResult.result()); // Done
    });
}

如果它将会是一个长时间运行的线程,也许最好不要使用默认的工作线程池,而是创建一个新的:

...
@PostConstruct
void init() {
    this.executor = vertx.createSharedWorkerExecutor("my-worker", 10);
}
    
void foo() {
    executor.<String>executeBlocking(promise -> {
        ...
    }
}

另一种实现这个的方法是使用Verticle


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