2010-08-21 62 views
12

我有一個使用Akka的Scala應用程序,它接收REST請求,對數據庫進行一些操作,並向客戶端返回一些信息。實際上,我的數據庫操作需要很長時間,而且我的REST支持的參與者無法同時響應新請求,即使我可以同時對數據庫同時運行大量操作。我在演員中使用javax.ws.rs註釋來啓用REST方法。如何擴展使用Akka的Scala REST應用程序?

這個問題;使我的應用程序能夠處理大量併發請求的最佳方式是什麼?

編輯:我會添加一些示例代碼。

import se.scalablesolutions.akka.actor._ 
    import javax.ws.rs._ 

    @Path("/test") 
    class TestService { 

    @GET 
    def status() = 
     actorPool !! Status(session). 
     getOrElse(<error>Unable to connect to service</error>) 
    } 

    class TestActor { 

    def receive = { 
     case Status() => { 
     reply(SomeObject.slowDBMethod) 
     } 
    } 
    } 

    case class Status() 

EDIT2:這是我收到在日誌中。我儘可能快地從瀏覽器發送這三個請求,因爲我可以切換標籤並按F5,但是RS bean在處理下一個請求之前仍然會等待第一個請求完成。

[INFO] [2010-08-29 16:27:03,232] [akka:event-driven:dispatcher:global-15] c.n.StatusActor: got Slow request 
[INFO] [2010-08-29 16:27:06,916] [akka:event-driven:dispatcher:global-10] c.n.StatusActor: got Slow request 
[INFO] [2010-08-29 16:27:10,589] [akka:event-driven:dispatcher:global-3] c.n.StatusActor: got Slow request 
+0

您可能想要查看Apache Bench而不是按F5這麼多用於併發測試的好工具。 http://httpd.apache.org/docs/2.2/programs/ab.html – cbmeeks 2012-12-14 04:28:37

回答

6

雖然我意識到這個線程現在已經過了4個月了,但值得注意的是Akka有一個新的HTTP模塊實現,可以將請求有效地轉換爲actor。這種方法利用了異步servlet API(也適用於Jetty的延續),以使被暫停的請求作爲消息通過系統傳遞並在任何時候恢復;消除,例如,需要使用!觸發演員的工作,並在註釋的POJO中作出迴應。同樣,由於請求在容器中被暫停,並且上下文被儘快地轉換爲actor,所以沒有線程阻塞來處理響應或未來。

一種簡單的方式上面的例子可以被改寫的今天:

class TestEndpoint extends Actor with Endpoint { 
    def hook(uri:String) = uri == "/test" 
    def provide(uri:String) = actorOf[TestService].start 

    override def preStart = { 
    ActorRegister.actorsFor[classOf[RootEndpoint]).head ! Endpoint.Attach(hook, provide) 
    } 

    def receive = handleHttpRequest 
} 

class TestService extends Actor { 
    def receive = { 

    case get:Get => 
     get.timeout(SomeObject.TimeoutInSeconds) // for example 
     get.OK(SomeObject.slowDBMethod) 

    case other:RequestMethod => 
     other.NotAllowed("Invalid method for this endpoint") 
    } 
} 

更多的文檔可以在阿卡網站上找到:http://doc.akkasource.org/http

3

一旦你得到一個請求,你應該創建一個新的actor來處理這個請求。傳遞原始發件人,以便新創建的演員知道應該回答的人。

+0

在一個'正常'演員的情況下,我希望這個工作。但在我的情況下,我無法真正傳遞添加的代碼示例的status()方法中的「發件人」?我假設無論我在接收方法中做什麼,只要status()方法尚未完成,actor就不會爲更多REST請求做好準備。 – Magnus 2010-08-21 23:29:50

+0

如何保持演員每用戶會話? – andreypopp 2010-08-22 10:23:08

7

您似乎正在使用舊版本的Akka。

我建議升級到0.10(分開演員和RS-豆類),那麼你可以使用負載平衡器1(和2)節流的工作量,或採取WorkStealingDispatcher 3的優勢(與4

這有幫助嗎?

+0

看起來很有希望。我會嘗試0.10。 – Magnus 2010-08-22 14:38:47

+0

我找不到akka-rest的0.10版本,至少在maven2存儲庫中。我應該使用0.8版本嗎? – Magnus 2010-08-22 16:09:58

+0

@Magnus請參閱http://doc.akkasource.org/getting-started#The%20Next%20Steps-Using%20Akka%20with%20Maven – 2010-08-23 01:19:03

1

雖然這個線程是舊的,我想補充漂亮(插頭!)進來:

https://github.com/mardambey/spiffy

什麼是漂亮?

漂亮......

  • 是用Scala編寫
  • 採用了夢幻般的阿卡庫和演員規模
  • 使用的servlet API 3。0異步請求處理
  • 採用模塊化(更換部件是直線前進)
  • 使用的DSL以減少代碼,你不希望它
  • 支持各地控制器

漂亮是要求掛鉤一個使用Scala的Web框架,Akka(一個Scala actor實現)以及Java Servelet 3.0 API。它利用異步界面,旨在爲Web應用程序提供大規模並行和可伸縮的環境。 Spiffy的各種組件都基於這樣的想法:它們需要是獨立的簡約模塊,能夠非常快速地完成少量工作,並將請求交給流水線中的下一個組件。在最後一個組件完成處理請求後,它通過「完成」請求並將其發送回客戶端來向servlet容器發送信號。

相關問題