微服务体系结构中的进程间通信



我们正在从单体架构应用程序转向微服务架构应用程序,我们仍处于规划阶段,我们想知道构建它的最佳实践是什么。

假设我们有两个服务:

  1. 用户
  2. Device
    • getUserDevices(UserId)
    • addDevice(DeviceInfo, UserId)

每个用户有多个设备

要求服务器获取所有用户设备的最常见,更干净和正确的方法是什么?

1- {api-url}/User/{UserId}/devices

需要另一个 HTTP 请求才能与设备服务通信。

对于用户 X,请从用户服务获取链接的设备。

2- {api-url}/Device/{UserId}/devices

对于用户 X,请从设备服务获取链接的设备。

在微服务中,有许多经典模式可用于解决此类问题。你有 2 个微服务 - 1 个用于用户(微服务 A),1 个用于设备(微服务 B)。微服务的基本原则是为每个微服务提供一个单独的数据库。如果任何微服务想要相互通信(或从另一个微服务获取数据),他们可以,但他们会使用 API 来完成。2 个微服务之间的另一种通信方式是事件。当微服务 A 中发生某些事情时,它将引发一个事件并将其推送到中央事件存储或消息队列,微服务 B 将订阅 A 发出的部分或全部事件。

我想在您的域中,A 将具有以下方法 - 添加/更新/删除用户,B 将具有添加/更新/删除设备。每个用户都可以拥有自己唯一的ID和其他数据字段,如姓名,地址,电子邮件等。每个设备都可以有自己的唯一ID,用户ID和其他数据字段,如名称,类型,制造商,价格等。每当"添加"设备时,都可以向设备微服务发送 POST 请求或命令(如果使用 CQRS),其中包含有关设备 + 用户 ID 的数据的请求,它可能会引发名为"DeviceAdd"的事件。它还可以具有与更新和删除相对应的事件,例如"设备已更新"和"设备已删除"。微服务 A 可以订阅 B 发出的事件 - "设备已添加"、"设备已删除"和"设备更新"事件,每当引发任何此类事件时,它都会处理该事件并将该事件非规范化到自己的设备小数据库中(可以调用 UserRelations)。将来,它也可以侦听来自其他微服务的事件(因此此处的模式将是可扩展和可扩展的)。

因此,现在要获取用户拥有的所有设备,您所要做的就是在用户微服务中创建一个端点,例如"http://{microservice-A-host}:{port}/user/{user-id}/devices",它将通过在自己的用户关系小数据库中查询user-id来返回设备列表,您必须通过事件维护该数据库。

很好的参考在这里:https://www.nginx.com/blog/event-driven-data-management-microservices/

它可能真的是任何一种方式,但根据我的喜好,我会选择将其放在/Devices/{userId}/devices 下,因为您正在寻找给定用户 ID 的设备。我希望这有所帮助。祝你好好吃!

您正在从服务请求资源,资源是设备,服务是设备服务。 从休息的角度来看,您正在寻找资源,并且您的服务提供了各种方法来操作该资源。

可以使用以下网址。

[GET] ../device?user_id=xyz

并且设备信息可以通过../device/{device_id}

话虽如此,如果您有一个同时提供用户和设备数据的服务,那么以下内容将是有意义的。

[GET] ../user/{userId}/device

请注意,这只是一个命名约定,您可以选择最适合您的,问题是选择一个并坚持下去。 公开 api 时,一致性更为重要。

微服务架构的一个核心原则是 定义每个微服务的明确边界和职责。

我可以说这与 SOLID 的单一责任原则相同,但在宏观层面上。 撇开这个原则不谈,我们得到:

用户
  • 服务负责用户管理/运营
  • 设备服务负责设备的操作

你的问题是

..要求服务器获取所有用户设备的正确方法

这是设备服务和用户服务的 100% 责任,对设备一无所知。

正如我所看到的,您只考虑路由术语(是的,API 一致性也很重要)。

从一侧看,更好,更合乎逻辑的URL是/api/users/{userId}/devices- 您尝试获取用户的设备,这些设备属于用户。

从另一侧,您可以使用/api/devices/user/{userId}(/api/devices/{deviceId})等路线,并且可以更轻松地处理 通过路由系统向设备服务发送请求。

考虑到其他约束,您可以选择适合您设计的选项。

还有少量补充:

需要另一个 HTTP 请求才能与设备服务通信。

在解决方案的体系结构中,可以创建一个额外的特殊且单独的组件,用于将请求路由到所需的微服务,不仅可以从一个微服务直接调用到另一个微服务。

应仅查询设备服务。

并将用户 ID 视为设备服务中的筛选器。例如:您应该搜索用户ID,类似于根据设备类型搜索设备的方式。只是另一个过滤器

例如 :/devices?userid=

您还可以在设备服务中缓存用户的一些基本信息,以节省获取用户数据的往返次数

对于微服务,这两个选项都没有错。但是deviceapi更有意义,而且我更喜欢

GET ../device/{userId}/devices

GET ../device?user_id=123

原因有二:

  1. 由于 userId 应该已经存在于设备服务中,因此您将节省对用户服务的一次调用。否则它会像请求者 -> 用户服务 -> 设备服务
  2. 您可以使用 POST ../device/{userId}/devices,为特定用户创建新设备。哪个看起来比参数化 URL 更宁静。

最新更新