scala Akka - 你应该创建多少个 actor 实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8113468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:39:34  来源:igfitidea点击:

Akka - How many instances of an actor should you create?

scalaakka

提问by Brian DiCasa

I'm new to the Akka framework and I'm building an HTTP server application on top of Netty + Akka.

我是 Akka 框架的新手,我正在 Netty + Akka 之上构建一个 HTTP 服务器应用程序。

My idea so far is to create an actor for each type of request. E.g. I would have an actor for a POST to /my-resource and another actor for a GET to /my-resource.

到目前为止,我的想法是为每种类型的请求创建一个参与者。例如,我将有一个演员用于 POST 到 /my-resource,另一个演员用于 GET 到 /my-resource。

Where I'm confused is how I should go about actor creation? Should I:

我感到困惑的是我应该如何进行演员创作?我是不是该:

  1. Create a new actor for every request (by this I mean for every request should I do a TypedActor.newInstance() of the appropriate actor)? How expensive is it to create a new actor?

  2. Create one instance of each actor on server start up and use that actor instance for every request? I've read that an actor can only process one message at a time, so couldn't this be a bottle neck?

  3. Do something else?

  1. 为每个请求创建一个新actor(我的意思是对于每个请求,我应该为适当的actor 执行 TypedActor.newInstance() 吗)?创建一个新演员的成本是多少?

  2. 在服务器启动时为每个参与者创建一个实例并为每个请求使用该参与者实例?我读过一个演员一次只能处理一条消息,所以这难道不是瓶颈吗?

  3. 做点别的?

Thanks for any feedback.

感谢您的任何反馈。

采纳答案by themel

Well, you create an Actor for each instance of mutable state that you want to manage.

好吧,您为要管理的每个可变状态实例创建一个 Actor。

In your case, that might be just one actor if my-resourceis a single object and you want to treat each request serially - that easily ensures that you only return consistent states between modifications.

在您的情况下,如果my-resource是单个对象并且您想按顺序处理每个请求,则可能只是一个参与者 - 这很容易确保您只在修改之间返回一致的状态。

If (more likely) you manage multiple resources, one actor per resource instance is usually ideal unless you run into many thousands of resources. While you can also run per-request actors, you'll end up with a strange design if you don't think about the state those requests are accessing - e.g. if you just create one Actor per POST request, you'll find yourself worrying how to keep them from concurrently modifying the same resource, which is a clear indication that you've defined your actors wrongly.

如果(更有可能)您管理多个资源,则每个资源实例一个参与者通常是理想的,除非您遇到数千个资源。虽然您也可以按请求运行 actor,但如果您不考虑这些请求正在访问的状态,您最终会得到一个奇怪的设计——例如,如果您只为每个 POST 请求创建一个 Actor,您会发现自己很担心如何防止它们同时修改相同的资源,这清楚地表明您错误地定义了您的演员。

I usually have fairly trivial request/reply actors whose main purpose it is to abstract the communication with external systems. Their communication with the "instance" actors is then normally limited to one request/response pair to perform the actual action.

我通常有相当琐碎的请求/回复参与者,其主要目的是抽象与外部系统的通信。他们与“实例”参与者的通信通常仅限于一对请求/响应来执行实际操作。

回答by Dan Bergh Johnsson

If you are using Akka, you can create an actor per request. Akka is extremely slim on resources and you can create literarily millions of actors on an pretty ordinary JVM heap. Also, they will only consume cpu/stack/threads when they actually do something.

如果您使用 Akka,您可以为每个请求创建一个参与者。Akka 的资源极其有限,您可以在一个非常普通的 JVM 堆上创建数百万个 actor。此外,它们只会在实际执行某些操作时消耗 cpu/stack/threads。

A year ago I made a comparisonbetween the resource consumption of the thread-based and event-based standard actors. And Akka is even better than the event-base.

一年前,我对基于线程和基于事件的标准 actor 的资源消耗进行了比较。Akka 甚至比事件库更好。

One of the big points of Akka in my opinion is that it allowsyou to design your system as "one actor per usage" where earlier actor systems often forced you to do "use only actors for shared services" due to resource overhead.

在我看来,Akka 的一大亮点是它允许您将系统设计为“每次使用一个参与者”,而早期的参与者系统通常会由于资源开销而迫使您“仅将参与者用于共享服务”。

I would recommend that you go for option 1.

我建议您选择选项 1。

回答by Didac Montero

Options 1) or 2) have both their drawbacks. So then, let's use options 3) Routing(Akka 2.0+)

选项 1) 或 2) 都有其缺点。那么,让我们使用选项3)路由(Akka 2.0+)

Router is an element which act as a load balancer, routing the requests to other Actors which will perform the task needed.

路由器是一个充当负载均衡器的元素,将请求路由到其他执行所需任务的 Actor。

Akka providers different Router implementations with different logic to route a message (for example SmallestMailboxPool or RoundRobinPool).

Akka 提供了具有不同逻辑的不同路由器实现来路由消息(例如 SmallestMailboxPool 或 RoundRobinPool)。

Every Router may have several children and its task is to supervise their Mailbox to further decide where to route the received message.

每个路由器可能有多个子节点,它的任务是监督它们的邮箱以进一步决定将接收到的消息路由到哪里。

//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");

This procedure is well explained in this blog.

这个过程在这个博客中有很好的解释。

回答by Alexey Romanov

  1. It's quite a reasonable option, but whether it's suitable depends on specifics of your request handling.

  2. Yes, of course it could.

  3. For many cases the best thing to do would be to just have one actor responding to every request (or perhaps one actor per type of request), but the only thing this actor does is to forward the task to another actor (or spawn a Future) which will actually do the job.

  1. 这是一个相当合理的选择,但它是否合适取决于您的请求处理的具体情况。

  2. 是的,当然可以。

  3. 在许多情况下,最好的做法是让一个 actor 响应每个请求(或者每种类型的请求可能有一个 actor),但这个 actor 唯一做的就是将任务转发给另一个 actor(或产生一个Future)这实际上可以完成这项工作。

回答by vijay

For scaling up the serial requests handling, add a master actor (Supervisor) which in turn will delegate to the worker actors (Children) (round-robin fashion).

为了扩大串行请求处理,添加一个主actor(Supervisor),它又将委托给workeractor(Children)(循环方式)。