2013-11-14 72 views
3

我有一組幾個在不同計劃下運行的Akka作業。最近,我添加了一些需要每天運行一次的作業,這些作業需要從磁盤讀取文件並處理數據。由於從磁盤讀取是阻止操作,因此當執行調度操作時,我的代碼將等待並且不運行任何預定作業。有誰知道調度線程不會被掛起的磁盤IO操作阻塞的方法嗎?我在下面包含了我的一個演員的代碼。使用阻止操作計劃重複作業

調度代碼:

lazy val system = akka.actor.ActorSystem("system") 
lazy val emailActor = system.actorOf(Props[EmailActor], name = "EmailActor") 

system.scheduler.schedule(3 hours, 24 hours)(emailActor ! System.currentTimeMillis) 

演員執行:

class EmailActor extends Actor { 
    override def receive = { 
    case _ => EmailSyncer.process() 
    } 
} 

處理器:

def process() = { 
    DataWarehouse.dataWarehouse withSession { 
    val file = "/some/file/name" 
    val emails = Try { Source.fromFile(file).getLines.map(l => Email(l)) } 

    ... 
    } 
} 
+0

將閱讀操作隔離爲單獨的演員? – Ashalynd

+0

我相信這就是我在安排工作時所做的。通過我目前正在運行的作業,它們通過相同的調度機制同時運行。 –

+0

好吧,如果你有幾個同時從磁盤讀取的作業,並且你正在讀取的文件很大,我能想到的唯一技術就是在每個塊之後讀取(相對較小的)數據塊中的數據並進行控制。 – Ashalynd

回答

3

這是在阿卡一個共同的問題。所以解決這個問題的模式很容易獲得。看看「Bulkheading」。我在下面寫了一篇博客文章,告訴你你需要做什麼。

總的想法是,你可以把不同的角色在不同的執行上下文或俚語「破壞區」。這使您可以將資源耗盡和其他問題避免滲入應用程序的其他部分。只有一個執行上下文觸發飢餓,沒有別的。

您還可以根據每個失敗區域正在進行的操作,對線程池進行不同的調整。通常,大量的線程用於阻塞操作,對於計算密集型的東西,每個內核可以從一個線程開始調試。

祝你好運。

http://letitcrash.com/post/40755146949/tuning-dispatchers-in-akka-applications

+0

事實證明,阻止IO不是我的問題。有一個例外,從來沒有打印堆棧軌跡。但是,這個答案對幫助我瞭解處理Akka資源耗盡非常有幫助。因此,我會給你接受的答案。 –

+0

謝謝=)一旦你的應用程序變大,將它放在你的後口袋裏。可以爲性能和容錯性帶來巨大差異。 –