gpt4 book ai didi

java - 在 Scala 和第三方 Java 库中使用 Akka 的最佳实践

转载 作者:搜寻专家 更新时间:2023-10-30 20:01:06 25 4
gpt4 key购买 nike

我需要使用 memcached Java API在我的 Scala/Akka 代码中。此 API 为您提供同步和异步方法。异步的返回 java.util.concurrent.Future .这里有一个关于在 Scala 中处理 Java Futures 的问题 How do I wrap a java.util.concurrent.Future in an Akka Future? .但是就我而言,我有两个选择:

  1. 将来使用同步 API 和包装阻塞代码并标记阻塞:

    Future {
    blocking {
    cache.get(key) //synchronous blocking call
    }
    }
  2. 使用异步 Java API 并每隔 n 毫秒对 Java Future 进行一次轮询,以检查 future 是否已完成(如上面链接问题中的答案之一所述)。

哪个更好?我倾向于第一个选项,因为轮询会极大地影响响应时间。 blocking{} block 不应该阻止整个池吗?

最佳答案

我总是选择第一个选项。但我的做法略有不同。我不使用 blocking 功能。 (实际上我还没有考虑过。)相反,我为包装同步阻塞调用的 Future 提供了一个自定义执行上下文。所以它看起来基本上是这样的:

val ecForBlockingMemcachedStuff = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(100)) // whatever number you think is appropriate
// i create a separate ec for each blocking client/resource/api i use

Future {
cache.get(key) //synchronous blocking call
}(ecForBlockingMemcachedStuff) // or mark the execution context implicit. I like to mention it explicitly.

因此所有阻塞调用都将使用专用的执行上下文(= 线程池)。因此它与负责非阻塞内容的主要执行上下文分离。

这种方法也在 online training video for Play/Akka 中进行了解释。类型安全提供。第 4 课中有一段视频介绍如何处理阻塞调用。它由 Nilanjan Raychaudhuri 解释(希望我拼写正确),他是著名的 Scala 书籍作者。

更新:我有一个 discussion with Nilanjan on twitter .他解释了 blocking 方法和自定义 ExecutionContext 方法之间的区别。 blocking 功能只是创建一个特殊的 ExecutionContext。它提供了一种简单的方法来解决您需要多少线程的问题。当池中所有其他现有线程都忙时,它每次都会产生一个新线程。所以它实际上是一个不受控制的ExecutionContext。它可能会创建大量线程并导致出现内存不足错误等问题。所以自定义执行上下文的解决方案实际上更好,因为它使这个问题变得显而易见。 Nilanjan 还补充说,如果这个池因请求而过载,您需要考虑熔断。

TLDR:是的,阻止调用很糟糕。 使用自定义/专用的 ExecutionContext 来阻止调用。还要考虑熔断。

关于java - 在 Scala 和第三方 Java 库中使用 Akka 的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25094568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com