从质量保证的角度来看Akka系统

时间:2015-03-24 10:30:25

标签: java scala concurrency akka distributed-computing

我一直在测试一个基于Akka的应用程序已有一个多月了。但是,如果我反思,我得出以下结论:

  1. 单独的Akka演员可以实现很多并发。我已达到每秒超​​过100,000条消息。这很好,只是消息传递。
  2. 现在,如果在一端有连接的netty层,或者你最终得到了akka actor最终进行数据库调用,REST调用,写入文件,整个系统就没有意义了。演员的邮箱已满,其吞吐量(此处,接收消息/秒的能力)变慢。
  3. 从质量保证的角度来看,这就像拥有一个巨大的管道,你可以强行抽取大量的水,它可以处理。但是,如果输入软管坏了,或者端点无法承受压力,那么这个巨大的管子是没用的。
  4. 我需要以下答案,以便我可以在系统中建议或验证:

    1. 如果阻塞调用如DB调用,REST调用是否由actor处理?或者它们只适用于消息传递?
    2. 可以这样,假设您需要将数百万台android / ios设备持续连接到您的akka​​系统。而不是套接字(如此不可靠)等,远程actor可以实现为持久连接吗?
    3. 可以在演员{{​​1}}中进行任何计算吗?像DB调用等
    4. 我会要求编辑通过这篇文章。我不能单独问所有这些。

2 个答案:

答案 0 :(得分:1)

1)是的,他们可以。但是这个操作应该在单独的(worker)actor中完成,它使用fork-join-pool和阻塞代码周围的scala.concurrent.blocking,它需要它来防止线程饥饿。如果目标系统(DB,REST等)支持多个并发连接,则可以使用akka的路由器(在池中为每个连接创建一个actor)。您还可以为多个不同的表(资源,队列等)生成多个actor,具体取决于您的事务隔离和存储的一致性要求。

另一种处理此问题的方法是使用带有确认的异步请求而不是阻塞。您也可以将阻塞操作放在一个单独的未来(线程,工作者)中,这将在操作结束时发送确认消息。

2)是的,actor可以实现为持久连接。它将只是一个持有连接状态的演员(因为演员是有状态的)。使用Akka Persistence可能更加可靠,这可以节省与某些存储的连接。

3)你可以在演员{{​​1}}中进行任何非阻塞计算(akka中没有receive方法)。 Akka Supervising将自动管理故障(如无法连接到DB)。有关阻止代码,请参阅1.

P.S。关于"巨大的管道"。后端应用程序本身就是一个管道(随着akka变得越来越大),所以如果环境无法处理它,没有什么可以帮助你提高性能 - 这个世界上没有泵。但是akka也是一个"水箱",这意味着外部压力可能比内部更强。顺便说一句,这意味着开发人员应该小心使用邮箱 - 因为"太多水"可能导致OutOfMemory,防止这种情况的方法是组织back pressure。可以通过不承认传入消息(或简单地阻止端点的处理程序)直到它由akka继续来完成。

答案 1 :(得分:0)

我不确定我能理解你的所有问题,但总的来说演员对慢工作也很好:

1)是的,他们完全没问题。只需为每个请求创建/分配1个actor(可能在akka路由器后面进行负载平衡),一旦完成,它可以将自己标记为"免费用于新工作"或自我终止。请记住将来执行慢速代码。就个人而言,由于隐式超时和吞咽异常,我喜欢避免询问/管道模式,只需使用带有请求ID的告诉,但如果你的延迟和错误率很低,请去询问/管道。

2)你可以,但在这种情况下,我建议建立一个连接池,而不是每次请求产生它们,因为这需要更长的时间。如果你能提供更多细节,我可以改进这个答案。

3)是的,但请想一想:演员很便宜。创造数百万个,每当有一个阻挡部分,它应该是一个不同的,专门的演员。将单一责任推向极致。如果你很少,阻止演员,你将失去所有的好处。