Scala中的Akka和第三方Java库的最佳实践

 李劲松在科岛每晚包夜 发布于 2022-12-31 00:35

我需要在我的Scala/Akka代码中使用memcached Java API.此API为您提供同步和异步方法.异步的返回java.util.concurrent.Future.这里有一个关于在Scala中处理Java Futures的问题如何在Akka Future中包装java.util.concurrent.Future?.但在我的情况下,我有两个选择:

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

    Future {
      blocking {
        cache.get(key) //synchronous blocking call
      } 
    }
    

    使用异步Java API并在Java Future上每隔n ms轮询一次以检查未来是否已完成(如上面链接问题中的上述答案之一所述).

哪一个更好?我倾向于第一种选择,因为轮询可以极大地影响响应时间.不应该blocking { }阻止阻止整个池?

1 个回答
  • 我总是选择第一个选项.但我这样做的方式略有不同.我不使用该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.
    

    因此,所有阻塞调用都将使用专用的执行上下文(= Threadpool).因此它与主要执行上下文分开,负责非阻塞内容.

    这种方法也在Typesafe提供的Play/Akka在线培训视频中进行了解释.第4课中有一个关于如何处理阻塞呼叫的视频.它由Nilanjan Raychaudhuri解释(希望我拼写正确),他是Scala书籍的着名作者.

    更新:我在推特上与Nilanjan进行了讨论.他解释了方法blocking和习惯之间的区别ExecutionContext.该blocking功能只是创造了一个特殊的ExecutionContext.它提供了一个简单的方法来解决您需要多少线程的问题.每当池中的所有其他现有线程都忙时,它就会生成一个新线程.所以它实际上是一个不受控制的 ExecutionContext.它可能会创建大量线程并导致内存不足错误等问题.因此,具有自定义执行上下文的解决方案实际上更好,因为它使这个问题变得明显.Nilanjan还补充说,你需要考虑电路中断,因为这个池会因请求而过载.

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

    2022-12-31 01:25 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有