Akka与设备组一起工作《twelve》译
Dependency
在项目中添加以下依赖项:
介绍:
让我们仔细看看我们的用例所需的主要功能,在用于监控家庭温度的完整物联网系统中,将设备传感器连接到我们系统的步骤可能如下所示:
- 家中的传感器设备通过某种协议连接。
- 管理网络连接的组件接受连接。
- 传感器提供其组和设备ID以向我们系统的设备管理器组件注册。
- 设备管理器组件通过查找或创建负责保持传感器状态的actor来处理注册。
- Actor回应一个确认,暴露其ActorRef。
- 网络组件现在使用ActorRef进行传感器和设备actor之间的通信,而无需通过设备管理器。
步骤1和2发生在我们的教程的范围之外。在本章中,我们将开始解决步骤3-6,并为传感器创建一种方式来注册我们的系统并与Actor进行通信。但首先,我们还有另一个架构决策 - 我们应该使用多少级别的Actor来代表设备组和设备传感器?
Akka程序员面临的主要设计挑战之一是为Actor选择最佳粒度。实际上,根据Actor之间交互的特征,通常有几种有效的方法来组织系统。例如,在我们的用例中,可以让一个Actor维护所有组和设备 - 可能使用哈希映射。为每个组建立一个跟踪同一家庭中所有设备状态的参与者也是合理的。
以下指南帮助我们选择最合适的actor层次结构:
- 通常,更喜欢先引入大的粒度,比需要的更细粒度的Actor会导致比解决的更多的问题。
- 在系统需要时添加更精细的粒度:
- 更高的并发性。
- 具有许多状态的Actor之间的复杂对话,我们将在下一章中看到一个很好的例子。
- 足够的状态,分成较小的角色是有意义的。
- 多个不相关的责任,使用单独的参与者可以使个人失败并恢复,而对他人的影响很小。
设备管理层次结构
考虑到上一节中概述的原则,我们将设备管理器组件建模为具有三个级别的Actor树:
- *管理员Actor代表设备的系统组件。它也是查找和创建设备组和设备角色的入口点。
- 在下一级别,组成员每个监督一个组ID(例如一个家庭)的设备角色。它们还提供服务,例如查询其组中所有可用设备的温度读数。
- 设备Actor管理与实际设备传感器的所有交互,例如存储温度读数。
出于以下原因,我们选择了这种三层架构:
拥有各个Actor的组:
- 隔离组中发生的故障。如果单个actor管理所有设备组,则导致重新启动的一个组中的错误将消除否则无故障的组的状态。
- 简化查询属于组的所有设备的问题。每个组actor仅包含与其组相关的状态。
- 增加系统的并行性。由于每个组都有一个专用的actor,它们可以同时运行,我们可以同时查询多个组。
将传感器建模为单个设备角色:
- 将一个设备actor的故障与组中的其余设备隔离。
- 增加收集温度读数的并行度。来自不同传感器的网络连接直接与其各个设备Actor通信,从而减少了争用点。
通过定义架构,我们可以开始使用协议来注册传感器。
注册协议
作为第一步,我们需要设计协议以注册设备和创建将负责它的组和设备Actor。此协议将由DeviceManager组件本身提供,因为它是唯一已知且可预先使用的Actor:按需创建设备组和设备Actor。
更详细地查看注册,我们可以概述必要的功能:
- 当DeviceManager收到包含组和设备ID的请求时:
- 如果经理已经拥有设备组的参与者,它会将请求转发给它。
- 否则,它会创建一个新的设备组Actor,然后转发该请求。
- DeviceGroup Actor接收注册给定设备的actor的请求:
- 如果组已经有设备的actor,则组actor将请求转发给设备actor。
- 否则,DeviceGroup Actor首先创建一个设备Actor,然后转发该请求。
- 设备参与者接收请求并向原始发送者发送确认。由于设备actor确认收到(而不是组actor),传感器现在将使用ActorRef将消息直接发送给其actor。
我们将用于传达注册请求及其确认的消息有一个简单的定义:
在这种情况下,我们没有在消息中包含请求ID字段。由于注册发生一次,当组件将系统连接到某个网络协议时,ID并不重要。但是,通常最佳做法是包含请求ID。
现在,我们将从下往上开始实施协议。在实践中,自上而下和自下而上的方法都可以工作,但在我们的情况下,我们从自下而上的方法中受益,因为它允许我们立即编写新功能的测试,而不会模拟我们需要的部分后来建造。
向设备角色添加注册支持
我们层次结构的底部是Device actors。他们在注册过程中的工作很简单:回复注册请求并向发件人发送确认。谨慎地对针对不匹配的组或设备ID的请求添加安全措施。
我们假设注册消息的发送者的ID保留在上层。我们将在下一部分向您展示如何实现这一目标。
设备actor***如下所示:
我们现在可以编写两个新的测试用例,一个执行成功注册,另一个测试ID不匹配的情况:
我们使用了TestKit中的expectNoMsg()辅助方法。此断言将一直等到定义的时间限制,如果在此期间收到任何消息,则会失败。如果在等待期间没有收到消息,则断言通过。保持这些超时较低(但不能太低)通常是一个好主意,因为它们会增加大量的测试执行时间。
下节再续!
原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_4.html
有什么讨论的内容,可以加我公众号: