2011-11-13 39 views
59

Tôi mới tham gia khuôn khổ Akka và tôi đang xây dựng một ứng dụng máy chủ HTTP trên đầu trang của Netty + Akka.Akka - Bạn cần tạo bao nhiêu lần diễn viên?

Ý tưởng của tôi cho đến nay là tạo một diễn viên cho từng loại yêu cầu. Ví dụ. Tôi sẽ có một diễn viên cho một POST đến/tài nguyên của tôi và một diễn viên khác cho một GET đến/tài nguyên của tôi.

Tôi đang bối rối ở đâu về cách tạo diễn viên? Tôi có nên:

  1. Tạo một diễn viên mới cho mọi yêu cầu (theo tôi có nghĩa là mọi yêu cầu tôi nên làm TypedActor.newInstance() của diễn viên thích hợp)? Làm thế nào đắt tiền để tạo ra một diễn viên mới?

  2. Tạo một phiên bản của mỗi tác nhân trên máy chủ khởi động và sử dụng cá thể tác nhân đó cho mọi yêu cầu? Tôi đã đọc rằng một diễn viên chỉ có thể xử lý một tin nhắn cùng một lúc, vì vậy đây không phải là một cái cổ chai?

  3. Làm điều gì đó khác?

Cảm ơn mọi phản hồi.

Trả lời

30

Vâng, bạn tạo một diễn viên cho từng trường hợp của trạng thái có thể thay đổi mà bạn muốn quản lý.

Trong trường hợp của bạn, đó có thể chỉ là một diễn viên nếu my-resource là một đối tượng duy nhất và bạn muốn xử lý từng yêu cầu một cách dễ dàng - đảm bảo rằng bạn chỉ trả về trạng thái nhất quán giữa các sửa đổi.

Nếu (nhiều khả năng) bạn quản lý nhiều tài nguyên, một diễn viên cho mỗi cá thể tài nguyên thường là lý tưởng trừ khi bạn chạy vào hàng nghìn tài nguyên. Mặc dù bạn cũng có thể chạy các tác nhân theo yêu cầu, bạn sẽ kết thúc với thiết kế lạ nếu bạn không nghĩ về trạng thái mà các yêu cầu đó đang truy cập - ví dụ: nếu bạn chỉ tạo một Actor cho mỗi yêu cầu POST, bạn sẽ thấy mình lo lắng cách giữ chúng đồng thời sửa đổi cùng một tài nguyên, đó là dấu hiệu rõ ràng rằng bạn đã xác định các diễn viên của mình sai.

Tôi thường có các diễn viên yêu cầu/trả lời khá tầm thường với mục đích chính là trừu tượng liên lạc với các hệ thống bên ngoài. Giao tiếp của họ với các diễn viên "thể hiện" sau đó thường được giới hạn trong một cặp yêu cầu/phản hồi để thực hiện hành động thực tế.

8
  1. Đó là một lựa chọn khá hợp lý, nhưng liệu nó có phù hợp hay không phụ thuộc vào các yêu cầu cụ thể về yêu cầu xử lý của bạn.

  2. Có, tất nhiên là có thể.

  3. Đối với nhiều trường hợp, điều tốt nhất cần làm là chỉ có một nam diễn viên đáp ứng mọi yêu cầu (hoặc có thể là một diễn viên cho mỗi loại yêu cầu), nhưng điều duy nhất diễn viên này làm là chuyển tiếp tác vụ cho một diễn viên khác (hoặc sinh ra một Future) mà thực sự sẽ thực hiện công việc.

+0

Trên 3), điều đó có nghĩa là nếu máy thực thi tác nhân có nhiều hơn một lõi, nó sẽ không được sử dụng đúng cách? – Diego

+1

@Diego Không, vì các diễn viên/tương lai, nó chuyển tiếp để có thể làm việc trên những lõi đó. –

3

Đối với nhân rộng việc xử lý các yêu cầu serial, thêm một diễn viên bậc thầy (Supervisor) mà lần lượt sẽ uỷ thác cho các diễn viên người lao động (Children) (round-robin fashion).

20

Nếu bạn đang sử dụng Akka, bạn có thể tạo một diễn viên theo yêu cầu.Akka cực kỳ mỏng manh về tài nguyên và bạn có thể tạo ra hàng triệu tác nhân trên một đống JVM khá bình thường. Ngoài ra, chúng sẽ chỉ tiêu thụ cpu/stack/threads khi chúng thực sự làm điều gì đó.

Một năm trước, tôi đã thực hiện comparison giữa mức tiêu thụ tài nguyên của các tác nhân tiêu chuẩn dựa trên chủ đề và dựa trên sự kiện. Và Akka thậm chí còn tốt hơn so với cơ sở sự kiện.

Một trong những điểm quan trọng của Akka theo ý kiến ​​của tôi là cho phép bạn thiết kế hệ thống của bạn là "một diễn viên cho mỗi lần sử dụng", nơi các hệ thống diễn viên trước đó thường buộc bạn thực hiện "chỉ sử dụng diễn viên cho dịch vụ được chia sẻ" để chi phí tài nguyên.

Tôi khuyên bạn nên chọn tùy chọn 1.

20

Tùy chọn 1) hoặc 2) có cả hai mặt hạn chế của chúng. Vì vậy, sau đó, hãy sử dụng tùy chọn 3) Routing (Akka 2.0+)

Router là một yếu tố mà hành động như một cân bằng tải, định tuyến các yêu cầu đối với diễn viên khác mà sẽ thực hiện nhiệm vụ cần thiết.

Các nhà cung cấp Akka khác nhau Triển khai bộ định tuyến với logic khác nhau để định tuyến thư (ví dụ SmallestMailboxPool hoặc RoundRobinPool).

Mỗi bộ định tuyến có thể có nhiều con và nhiệm vụ của nó là giám sát hộp thư của chúng để quyết định tiếp tục định tuyến thư đã nhận.

//This will create 5 instances of the actor ExampleActor 
//managed and supervised by a RoundRobinRouter 
ActorRef roundRobinRouter = getContext().actorOf(
Props.create(ExampleActor.class).withRouter(new RoundRobinRouter(5)),"router"); 

Quy trình này được giải thích rõ trong this blog.

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