scala - 使用 Scala Akka 框架来阻止 CLI 调用

标签 scala akka blocking

我对 Akka 和 Scala 比较陌生,但我想使用 Akka 作为通用框架来收集来自各种 Web 工具和 cli 命令的信息。

我理解在 Actor 模型中的一般原则,非常希望不要让 Actor 阻塞。对于 http 请求,有异步 http 客户端(例如 Spray),这意味着我可以在 Actor 框架内异步处理请求。

但是,我不确定将参与者与现有的阻塞 API 调用(例如 scala ProcessBuilder/ProcessIO 库)结合起来的最佳方法是什么。在发出这些 CLI 命令方面,我预计并发量相对较少,例如可能在 12 核机器上执行最多 10 个并发 CLI 调用。

让单个参与者管理这些 CLI 命令,将实际工作分配给根据需要创建的 Future 是否更好?或者仅仅维护一组由 PinnedDispatcher 支持的独立参与者会更干净吗?或者是其他东西?

最佳答案

来自 Akka 文档(http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html#Blocking_Needs_Careful_Management):

"
阻塞需要细心管理

在某些情况下,不可避免地会进行阻塞操作,即让线程休眠一段不确定的时间,等待外部事件发生。示例是遗留的 RDBMS 驱动程序或消息传递 API,并且通常(网络)I/O 发生在幕后的根本原因。面对这种情况时,您可能想将阻塞调用包装在 Future 中并使用它来代替,但是这种策略太简单了:当应用程序运行时,您很可能会发现瓶颈或内存或线程不足在增加的负载下。

“阻塞问题”的适当解决方案的非详尽列表包括以下建议:

  • 在一个actor(或由路由器[Java,Scala]管理的一组actor)内进行阻塞调用,确保配置一个专用于此目的或足够大的线程池。
  • 在 Future 中进行阻塞调用,确保在任何时间点此类调用的数量都有上限(提交无限数量的这种性质的任务将耗尽您的内存或线程限制)。
  • 在 Future 中执行阻塞调用,为线程池提供一个线程数上限,该上限适用于运行应用程序的硬件。
    专用单个线程来管理一组阻塞资源(例如,驱动多个 channel 的 NIO 选择器)并在事件作为参与者消息发生时分派(dispatch)事件。

  • 第一种可能性特别适合本质上是单线程的资源,例如传统上一次只能执行一个未完成的查询并使用内部同步来确保这一点的数据库句柄。一种常见的模式是为 N 个参与者创建一个路由器,每个参与者都包装一个 DB 连接并处理发送到路由器的查询。然后必须调整数字 N 以获得最大吞吐量,这将取决于部署在什么硬件上的 DBMS。”

    关于scala - 使用 Scala Akka 框架来阻止 CLI 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12915570/

    相关文章:

    java - 使用 Akka(使用 Java)如何验证我的被测 Actor 正在观看另一个 Actor ?

    c - 套接字:是什么导致 read() 返回 EINVAL?

    java - 如何重定向 AWS sdk 日志记录输出

    ruby - 如何同时使用 scala 和 rails 中的 memcached(Amazon elasticache)?

    scala - 如何在一段距离 "in"(ala takeWhile)中启动 Scala 流?

    sql - 如何为 PostgreSQL 编写我自己的全局锁定/解锁函数

    c++ - 为无锁队列添加阻塞函数

    eclipse - scala eclipse IDE 够稳定吗?

    Akka 和 SLF4J 配置

    java - 更新有限状态机中的数据