我对 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 中并使用它来代替,但是这种策略太简单了:当应用程序运行时,您很可能会发现瓶颈或内存或线程不足在增加的负载下。
“阻塞问题”的适当解决方案的非详尽列表包括以下建议:
专用单个线程来管理一组阻塞资源(例如,驱动多个 channel 的 NIO 选择器)并在事件作为参与者消息发生时分派(dispatch)事件。
第一种可能性特别适合本质上是单线程的资源,例如传统上一次只能执行一个未完成的查询并使用内部同步来确保这一点的数据库句柄。一种常见的模式是为 N 个参与者创建一个路由器,每个参与者都包装一个 DB 连接并处理发送到路由器的查询。然后必须调整数字 N 以获得最大吞吐量,这将取决于部署在什么硬件上的 DBMS。”
关于scala - 使用 Scala Akka 框架来阻止 CLI 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12915570/