微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

quarkus 反应式叛变线程池管理

如何解决quarkus 反应式叛变线程池管理

背景:我这周才开始使用 Quarkus,尽管我之前曾使用过一些流媒体平台(尤其是 Scala 中的 http4s/fs2)。

使用 quarkus 反应式(使用 mutiny)和任何反应式数据库客户端(mutiny 反应式 postgres、反应式 elasticsearch 等)我有点困惑如何正确管理阻塞调用和线程池。

quarkus 文档建议使用 @Blocking 注释命令式代码cpu 密集型代码,以确保将其转移到工作池而不阻塞 IO 池。这是有道理的。

考虑以下事项:

public class Stuff {
  // imperative,cpu intensive
  public static int cpuIntensive(String arg) { /* ... */ }

  // blocking IO
  public static List<Integer> fetchFromDb() { /* ... */ }

  // reactive IO
  public static Multi<String> fetchReactive() { /* ... */ }

  // reactive IO with cpu processing
  public static Multi<String> fetchReactivecpuIntensive(String arg) {
    fetchReactive() // reactive fetch
      .map(fetched -> cpuIntensive(arg + fetched)) // cpu intensive work
  }
}

我不清楚上述每个条件中会发生什么,以及如果它们被一个没有 @Blocking 注释的 resteasy-reactive rest 端点调用,它们会在何处执行。 >


据推测,在没有 @Blocking 的反应式休息端点中使用任何反应式客户端都是安全的。但是在 Uni 中包装阻塞调用对“不安全”clode 来说是否完成了同样的工作?也就是说,返回 Multi/Uni 的任何东西都会在 worker 池中有效运行吗?

(我将打开关于更好地控制线程池的后续帖子,因为我认为没有任何方法可以将反应式 IO 调用“转移”到单独的池而不是 cpu 密集型工作,这将是最佳的。)

编辑

这个问题可能暗示我在询问返回类型(Uni/Multi 与直接对象),但实际上是关于在任何给定时间选择正在使用的线程池的能力。 this mutiny page on imperative-to-reactive 有点实际上回答了我的问题,还有 mutiny infrastructure docs 声明“认执行程序已配置为使用 Quarkus 工作线程池。”,以及 {{ 3}} 处理我认为的其余部分。

所以我的理解是这样的:

如果我有一个端点,有条件可以返回非阻塞的东西(例如本地非阻塞缓存命中),那么我可以有效地在 IO 线程上以我想要的任何方式返回。但是,如果所述缓存未命中,我可以直接调用反应式客户端或使用 mutiny 在 quarkus 工作池上运行阻塞操作。同样,mutiny 提供了在特定线程池(执行器)上执行任何给定流的控制。

响应式客户端(或在非 IO 池上有效运行的任何东西)可以安全调用,因为 IO 循环只是订阅工作池发出的数据。

最后,我似乎可以将 cpu 绑定池与 IO 绑定工作池分开配置,并将它们作为 executor 明确提供给我需要的任何发射器。所以......我想我现在已经准备好了。

解决方法

这是一个很好的问题!

RESTEasy Reactice 端点的返回类型不会对端点将在哪个线程上提供服务有任何影响。 唯一决定线程的是 @Blocking / @NonBlocking 的存在。

原因很简单:仅仅使用返回类型,无法知道操作是否真的需要很长时间才能完成(从而阻塞线程)。 例如,非反应返回类型并不意味着该操作是 CPU 密集型的(例如,您可能只是返回一些固定的 JSON 响应)。 另一方面,反应类型不能保证操作是非阻塞的,因为正如您提到的,用户可以简单地用反应返回类型包装阻塞操作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?