我是Akka框架的新手,我正在Netty + Akka上构建一个HTTP服务器应用程序.
到目前为止,我的想法是为每种类型的请求创建一个actor.例如,我有一个POST到/ my-resource的actor和另一个GET到/ my-resource的actor.
在哪里我感到困惑的是我应该如何创作演员呢?我是不是该:
为每个请求创建一个新的actor(我的意思是我应该为每个请求做一个相应的actor的TypedActor.newInstance())?创建新演员有多贵?
在服务器启动时创建每个actor的一个实例,并为每个请求使用该actor实例?我读过一个演员一次只能处理一条消息,所以这不是瓶颈吗?
做点别的吗?
感谢您的任何反馈.
好吧,您为要管理的每个可变状态实例创建一个Actor.
在您的情况下,如果my-resource
是单个对象,并且您希望按顺序处理每个请求,那么这可能只是一个actor - 这很容易确保您只在修改之间返回一致的状态.
如果(更有可能)您管理多个资源,每个资源实例一个actor通常是理想的,除非您遇到数千个资源.虽然你也可以运行每个请求的actor,如果你不考虑那些请求正在访问的状态,你最终会得到一个奇怪的设计 - 例如,如果你只是为每个POST请求创建一个Actor,你会发现自己很担心如何防止他们同时修改同一个资源,这清楚地表明你已经错误地定义了你的演员.
我通常有相当琐碎的请求/回复演员,其主要目的是抽象与外部系统的通信.然后,它们与"实例"参与者的通信通常限于一个请求/响应对来执行实际动作.
如果您使用的是Akka,则可以根据请求创建一个actor.Akka在资源上非常渺茫,你可以在非常普通的JVM堆上创建数百万个演员.此外,他们只会在实际执行某些操作时使用cpu/stack/threads.
一年前,我对基于线程和基于事件的标准参与者的资源消耗进行了比较.Akka甚至比活动基地更好.
在我看来,Akka的一个重点是它允许你将你的系统设计为"每次使用的一个角色",早期的演员系统经常强迫你做"由于资源开销而只使用演员来共享服务".
我建议你去选项1.
选项1)或2)都有它们的缺点.那么,让我们使用选项3)路由(Akka 2.0+)
路由器是一个充当负载均衡器的元素,将请求路由到将执行所需任务的其他Actors.
Akka提供不同的路由器实现,使用不同的逻辑来路由消息(例如SmallestMailboxPool或RoundRobinPool).
每个路由器可能有几个孩子,其任务是监督他们的邮箱,以进一步决定在哪里路由收到的消息.
//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");
本博客中详细解释了此过程.
这是一个非常合理的选择,但它是否合适取决于您的请求处理的具体情况.
是的,当然可以.
对于许多情况,最好的办法是让一个actor响应每个请求(或者每个请求类型一个actor),但这个actor唯一能做的就是将任务转发给另一个actor(或者生成一个Future
)这实际上会完成这项工作.