2010-08-21 25 views
12

Tôi có một ứng dụng Scala sử dụng Akka nhận các yêu cầu REST, thực hiện một số hoạt động đối với một cơ sở dữ liệu và trả lời một số thông tin cho khách hàng. Do đó, các hoạt động db của tôi mất một thời gian dài và diễn viên được kích hoạt REST của tôi không thể đáp ứng các yêu cầu mới trong khi chờ đợi, mặc dù tôi có thể chạy nhiều hoạt động đồng thời với DB. Tôi đang sử dụng các chú thích javax.ws.rs cho các phương thức REST-enable trong diễn viên của tôi.Làm cách nào để mở rộng ứng dụng Scala REST sử dụng Akka?

Câu hỏi; cách tốt nhất để cho phép ứng dụng của tôi xử lý một số lượng lớn các yêu cầu đồng thời là gì?

EDIT: Tôi sẽ thêm một số mã mẫu.

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: Đây là những gì tôi nhận được trong nhật ký. Tôi đang gửi ba yêu cầu từ trình duyệt của tôi nhanh như tôi có thể chuyển đổi các tab và nhấn F5, nhưng hạt RS vẫn chờ yêu cầu đầu tiên hoàn thành trước khi xử lý tiếp theo.

[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

Bạn có thể muốn xem xét Apache Bench thay vì nhấn F5 rất nhiều công cụ tuyệt vời để kiểm tra đồng thời. http://httpd.apache.org/docs/2.2/programs/ab.html – cbmeeks

Trả lời

6

Trong khi tôi nhận ra chuỗi này đã cũ hơn 4 tháng, đáng lưu ý là Akka có một triển khai mô-đun HTTP mới để chuyển yêu cầu đó thành một diễn viên hiệu quả. Cách tiếp cận này thúc đẩy API servlet không đồng bộ (cũng làm việc với các tiếp nối Jetty) để cho phép yêu cầu bị treo được truyền qua hệ thống dưới dạng tin nhắn và tiếp tục tại bất kỳ điểm nào; loại bỏ, ví dụ, sự cần thiết phải sử dụng !! để kích hoạt tác nhân của diễn viên và trả lời trong POJO được chú thích. Tương tự như vậy, vì yêu cầu bị tạm ngưng trong vùng chứa và ngữ cảnh được chuyển thành một diễn viên nhanh nhất có thể, không có luồng nào chặn để xử lý phản hồi hoặc tương lai.

Một cách ngây thơ ví dụ trên có thể được viết lại ngày hôm nay:

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") 
    } 
} 

tài liệu hướng dẫn thêm có thể được tìm thấy trên trang web AKKA: http://doc.akkasource.org/http

3

Khi bạn nhận được yêu cầu, bạn nên tạo một diễn viên mới để xử lý yêu cầu đó. Chuyển cho người gửi ban đầu để diễn viên mới được tạo biết người trả lời.

+0

Trong tình huống diễn viên 'bình thường', tôi hy vọng điều đó sẽ hoạt động. Nhưng trong trường hợp của tôi, tôi không thể thực sự truyền "người gửi" trong phương thức status() của mẫu mã được thêm vào? Tôi giả định rằng bất cứ điều gì tôi làm trong phương thức nhận, tác nhân sẽ không sẵn sàng cho các yêu cầu REST nhiều hơn miễn là phương thức status() chưa hoàn thành. – Magnus

+0

Làm cách nào để giữ diễn viên cho mỗi phiên người dùng? – andreypopp

7

bạn dường như đang sử dụng phiên bản cũ hơn của Akka.

Tôi khuyên bạn nên nâng cấp lên 0.10 (mà tách diễn viên và RS-Đậu), sau đó bạn có thể sử dụng loadbalancer 1 (và 2) để điều tiết khối lượng công việc, hoặc tận dụng các WorkStealingDispatcher 3 (và 4)

Điều đó có hữu ích không?

+0

Điều đó có vẻ đầy hứa hẹn. Tôi sẽ thử 0.10. – Magnus

+0

Tôi không thể tìm thấy phiên bản 0.10 của akka-rest, ít nhất là trong kho lưu trữ maven2. Tôi có nên sử dụng phiên bản 0.8 không? – Magnus

+0

@Magnus Xem http://doc.akkasource.org/getting-started#The%20Next%20Steps-Using%20Akka%20with%20Maven –

1

Mặc dù chủ đề này trở về già, tôi muốn thêm Spiffy (cắm!) để trộn:

https://github.com/mardambey/spiffy

Spiffy là gì?

Spiffy ...

  • được viết bằng Scala
  • sử dụng thư viện Akka tuyệt vời và diễn viên để mở rộng
  • sử dụng servlet API 3.0 để xử lý yêu cầu không đồng bộ
  • được mô-đun (thay thế các thành phần là thẳng về phía trước)
  • sử dụng DSL để cắt giảm trên mã mà bạn không muốn nó
  • hỗ trợ móc yêu cầu xung quanh bộ điều khiển

Spiffy là một khung công tác web sử dụng Scala, Akka (triển khai diễn viên Scala) và API Servelet 3.0 của Java. Nó sử dụng giao diện async và nhằm cung cấp một môi trường rộng lớn song song và có thể mở rộng cho các ứng dụng web. Các thành phần khác nhau của Spiffy đều dựa trên ý tưởng rằng chúng cần phải là các mô-đun tối giản độc lập làm một lượng nhỏ công việc rất nhanh chóng và đưa ra yêu cầu cho thành phần tiếp theo trong đường ống. Sau khi thành phần cuối cùng được thực hiện xử lý yêu cầu, nó báo hiệu container servlet bằng cách "hoàn thành" yêu cầu và gửi nó trở lại máy khách.

Các vấn đề liên quan