java - QA 视角下的 Akka 系统

标签 java scala concurrency akka distributed-computing

我已经测试一个基于 Akka 的应用程序一个多月了。但是,如果我反射(reflection)一下,我有以下结论:

  1. 单独使用 Akka actor 可以实现大量并发。我已经达到了超过 100,000 条消息/秒。这很好,只是消息传递。
  2. 现在,如果一端有用于连接的 netty 层,或者您最终使用 akka actor 进行数据库调用、REST 调用、写入文件,那么整个系统就不再有意义了。 Actor 的邮箱已满,他们的吞吐量(此处为每秒接收消息的能力)变慢。
  3. 从 QA 的角度来看,这就像有一个巨大的管道,您可以在其中强行泵入大量水并且它可以处理。但是,如果输入软管坏了,或者端点无法承受压力,那么这个巨大的管道就没有用了。

我需要以下问题的答案,以便我可以在系统中建议或验证:

  1. 像 DB 调用、REST 调用这样的阻塞调用应该由 actor 处理吗?或者它们只适用于消息传递?
  2. 是否可以这样说,假设您需要将数百万个 android/ios 设备持续连接到您的 akka 系统。除了套接字(如此不可靠)等,远程参与者是否可以实现为持久连接?<​​/li>
  3. 是否可以在 actor 的 handleMessage() 中进行任何类型的计算?像数据库调用等。

我会要求编辑通过这篇文章。我不能单独询问所有这些。

最佳答案

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

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

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

3) 您可以在 actor 的 receive 中进行任何非阻塞计算(akka 中没有 handleMessage 方法)。失败(比如没有连接到数据库)将由 Akka Supervising 自动管理。阻塞代码见1。

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

关于java - QA 视角下的 Akka 系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29230225/

相关文章:

function - Scala Map,元组和函数参数列表之间的歧义

scala - Scala 中 TypedDataset 和类型界限的隐式编码器

java - 如何使用java并发读取数据?

python - 提高spark sql的并行性

java - 如何正确地多线程独立任务的集合?

Java 泛型和多态性

Java Websocket 文本帧长度 >=128 时出错?

scala - 清除 Scala 工作表的输出

java - 将相同的 keystore 用于信任库和服务器库时出现安全问题?

scala - Akka消息限制