【发布时间】:2018-01-17 08:49:36
【问题描述】:
目前我正在设计和编程一个控制一系列设备的软件。该软件计划有一个 REST 接口,您可以通过该接口远程控制软件(和设备)。
现在,架构的一个非常基本的抽象可能看起来像这样:
如您所见,该系统由一个主控制器组成,该控制器然后处理和监控彼此不依赖的不同模块。前端模块是图中的一个示例,而其他模块是模块的一般抽象,但它们可以是任何东西(数据库模块、消息总线模块等)。 对于实际的 REST 接口,有数据检索、数据存储以及正在实现的控制命令。
我的“问题”是我无法决定这些“命令”应该如何传播。 一些可能的命令情况:
- 请求打开/关闭、重启、控制由另一个模块处理的设备的命令
- 请求重新启动/重新加载软件的命令
- 从另一个模块检索数据的命令
现在我看到了一些实际逻辑实现的可能方式:
- 所有收到的 REST 命令都通过消息总线发送。在这种情况下,每个请求都应该收到一个唯一标识符,然后可以使用该标识符来检索请求的状态
- 所有收到的 REST 命令都直接调用其他模块
这两种方法各有利弊: 做所有事情的第二种方法很容易陷入意大利面条代码,并且很难调试和扩展,因为通过不同的模块有很多多线程利用。但这可能是处理命令和检索数据的最快方式。特别是因为该项目需要速度和响应能力。 第一种方法没有第二种方法的优点,但是它有助于保持代码和架构的干净,并清除与其他模块的依赖关系。此外,还计划了一个控制台通道,理论上可以使用相同的方法来实施。
我在集思广益时想到了另一种方法: 强制 REST 通道将传入请求转发到实际的 FronEnd 模块,然后“等待”直到它收到响应。然后,前端模块必须直接调用其他模块以获取任何请求的信息或操作。 然而,这种方法与第 2 种方法并没有那么“不同”。
有人可以提供任何建议吗?也许是关于实施或设计决策的想法?
如果您想知道,该软件是用 Python 编写的,但我认为这与问题无关。
【问题讨论】:
-
IMO,您的上下文非常适合使用某些消息代理系统,例如 Apache Kafka (kafka.apache.org) 或 RabbitMQ (rabbitmq.com)。这些模块可以向/从 Master 生成/使用消息,并以比简单的 REST API 更健壮的方式进行通信。 (也推荐用于处理多个设备,以及日志记录功能)。也许这不是您想要的,但值得研究。
-
非常感谢。已经有这样一个系统可以实现模块之间的内部通信。由于 REST api 将用于有一些操作员(前端用户)控制,如果我也将消息总线用于 REST,我会警惕任何可能的延迟问题。此外,可能存在操作员需要立即反馈的情况,但是对于消息总线系统,您需要进行另一个调用(或使用 websockets 进行操作)来检索请求的响应。这会增加时间和额外的资源使用。
标签: python multithreading rest design-patterns restful-architecture