当前位置: 首页 > 知识库问答 >
问题:

quarkus反应性兵变线程池管理

帅煌
2023-03-14

背景:本周我刚刚开始学习Quarkus,尽管我以前使用过一些流媒体平台(特别是scala中的http4s/fs2)。

工作与夸克斯反应性(与兵变)和任何反应性数据库客户端(兵变反应性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反应性restendpoint调用它们,它们将在何处执行。

在反应性Rest终结点中使用任何反应性客户端可能是安全的,而不需要@Block。但是,在Uni中包装阻塞调用是否对不安全的Clode有同样的效果?也就是说,返回/Uni的任何内容是否会在辅助角色池中有效运行?

(我将打开后续文章,介绍如何更好地控制线程池,因为我看不到比cpu密集型工作更能将反应式IO调用“转移”到单独的池中,这是最佳的。)

编辑

这个问题可能意味着我在询问返回类型(Uni/Multivs direct objects),但实际上是关于在任何给定时间选择正在使用的线程池的能力。这个关于强制反应的mutiny页面实际上回答了我的问题,还有mutiny infrastructure文档,其中声明“默认执行器已配置为使用Quarkus工作线程池”,我认为mutiny线程控制文档处理其余的问题。

所以我的理解是这样的:

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

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

最后,似乎我可以分别配置cpu绑定池和IO绑定工作池,并将它们显式地作为executors提供给我需要的任何发射器。所以我想我已经准备好了。

共有1个答案

汪辰阳
2023-03-14

这是一个很好的问题!

RESTEasy Reactice终结点的返回类型不会对终结点将在哪个线程上提供服务产生任何影响。决定线程的唯一因素是@Block/@NonBlock的存在。

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

 类似资料:
  • TL;DR:哪种模式更常见?使用Mutiny Imperative resteasy,还是只使用resteasy? 我的理解是,哗变允许我传递给Quarkus一个更长的运行动作,并让它处理代码如何在上下文中运行的细节。使用被动技能比兵变命令有同等或更多的好处吗?如果从功能的角度看,从线程处理的角度看,它是相等的或者更好,那么Reactive将是很好的,因为它需要更少的代码来维护(创建uni,等等)

  • 当我到达endpoint时,我会得到这个资源: 这是我的代码: 这些是我的quarkus项目依赖项: 有什么想法吗?

  • 实际上,我使用野飞JEE服务器并考虑切换到Quarkus。关于quarkus,我有以下问题: 1.坚持。xml 我看到夸克斯使用自己的来建立数据库。我可以用来代替吗? 2.容器管理的持久性 quarkus是否提供了类似的功能,还是我必须自己管理持久性?

  • 我试图在同一个事务中执行3个插入,但当其中一个插入失败时,我无法回滚事务。 我是反应式世界的新手,这是我的第一个反应式应用。 下面是数据库模型的简化: 我想在同一事务中执行以下插入: 但是,当第二次插入失败时,第一次插入不会回滚。 我有以下课程: :接收来自Kafka的消息,并通过服务触发插入 :使用3个DAO运行3个插入 :运行实体A的插入 :运行实体B的插入 :运行实体C的插入 和类似于。 我

  • 我正在尝试用quarkus、hibernate和postgres开发一个多租户应用程序。 Hibernate Responsive通过让implement支持多租户: http://hibernate.org/reactive/documentation/1.0/reference/html_single/#_custom_connection_management_and_multitenanc

  • 在我们的应用程序中,我们使用Hystrix,因为我们调用了几个外部服务。我们希望为我们调用的每个外部服务配置一个具有特定大小的线程池。 假设有三个外部服务,称为S1、S2、S3。此外,我们有10个扩展的类,称为C1到C10。 C1和C2调用S1,应该使用相同的线程池,有15个线程。在C1的构造函数内部,我们对进行以下调用: 在一个命令(C1)的构造函数中,我们将S1的线程池大小指定为15。是一个自