2012-10-16 14 views
4

我對Akka相對較新& Scala,但我想使用Akka作爲通用框架將各種Web工具和cli命令的信息彙集在一起​​。使用Scala Akka框架阻止CLI調用

我明白在Actor模型中,非常希望不讓演員阻止。而對於http請求,有異步http客戶端(如Spray),這意味着我可以在Actor框架內異步處理請求。

但是,我不確定什麼是將演員與現有的阻止API調用(如scala ProcessBuilder/ProcessIO庫)結合使用時的最佳方法。就發行這些CLI命令而言,我期望相對少量的併發性,例如可能在12核心機器上最多執行10個併發CLI調用。

讓單個角色管理這些CLI命令,將實際工作轉移到根據需要創建的Futures是否更好?或者只是維護一組由PinnedDispatcher支持的獨立參與者會更簡潔?或者是其他東西?

回答

4

從阿卡文檔(http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html#Blocking_Needs_Careful_Management):

阻塞需要謹慎管理。

在某些情況下,這是不可避免做阻塞操作,也就是將一個線程的睡眠不確定的時間,等待外部事件的發生,例如傳統的RDBMS驅動程序或消息傳遞API,以及通常(網絡)I/O出現在封面下的基本原因,面對這種情況時,您可能會試圖將阻止Future內部的通話並使用相反,但這種策略太簡單了:當應用程序在增加的負載下運行時,您很可能找到瓶頸或內存不足或線程不足的情況。

向「阻塞問題」的適當辦法的非詳盡清單包括了以下建議:

  • 做一個演員中的阻塞調用(或通過路由器[Java中,斯卡拉管理一組演員]),確保配置專用於此目的或足夠大小的線程池。
  • 在Future中執行阻塞調用,確保在任何時間點上調用此類調用數量的上限(提交無限數量的此類任務將耗盡您的內存或線程限制)。
  • 在Future中執行阻塞調用,爲線程池提供適用於運行該應用程序的硬件的線程數上限。 專用單個線程來管理一組阻塞資源(例如,驅動多個通道的NIO選擇器),並在事件作爲參與者消息發生時分派事件。

第一種可能性特別適用於本質上是單線程的資源,例如傳統上一次只能執行一個未完成查詢的數據庫句柄並使用內部同步來確保這一點。一種常見模式是爲N個參與者創建一個路由器,每個參與者包裝單個數據庫連接並處理髮送給路由器的查詢。然後必須調整數量N以獲得最大吞吐量,這將取決於哪個DBMS部署在哪個硬件上而變化。「