微服务之间的通信——请求数据
Communication between microservices - request data
我正在处理微服务之间的通信。
例如(虚构的例子,仅供说明):
- 微服务 A - 存储用户(getUser 等)
- 微服务 B - 商店订单(createOrder 等)
现在如果我想从客户端应用添加新订单,我需要知道用户地址。所以请求会是这样的:
客户端 -> 微服务 B(为 userId 5 创建订单)-> 微服务 A(getUser with id 5)
微服务 B 将使用来自用户微服务的详细信息(地址)创建订单。
要解决的问题:如何有效地处理微服务 A 和微服务 B 之间的通信,因为我们必须等到响应返回?
选项:
- 使用 RestAPI,
- 使用 AMQP,比如 RabbitMQ,并通过 RPC 处理这个问题。 (https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html)
我不知道什么对性能更好。通过 RabbitMQ 或 RestAPI 调用速度更快吗? 微服务架构的最佳解决方案是什么?
就我个人而言,我不喜欢为 RPC 使用消息代理。它增加了不必要的复杂性和开销。
如何在用户 Web 服务中托管长期存在的 RabbitMQ 消费者?如果你把它做成一些静态单例,在你的网络服务中你如何处理缩放和并发?或者你让它成为一个独立的守护进程?现在您有两个用户应用程序而不是一个。如果您的用户消费者速度变慢会发生什么,当它使用请求消息时订单服务上下文可能已经超时并发送另一条消息或放弃。
对于 RPC,我建议使用简单的 HTTP。
有一种涉及消息代理的模式可以避免同步网络调用的需要。该模式用于服务使用来自其他服务的事件并将该数据本地存储在自己的数据库中。然后当订单服务需要用户记录时,它可以从自己的数据库访问它。
在您的情况下,您的用户应用程序不需要了解有关订单的任何信息,但您的订单应用程序需要了解有关您的用户的一些详细信息。因此,每次添加、修改、删除用户等时,用户服务都会发出一个事件(UserCreated、UserModified、UserRemoved)。 Orders 服务可以订阅这些事件并仅存储它需要的数据,例如用户地址。
好处是在请求时,您的订单服务对另一服务的同步依赖性较低。测试服务更容易,因为您的请求时间依赖性更少。然而,也存在一些缺点,例如用户记录更改发生和订单应用程序接收之间的一些延迟。需要考虑的事情。
更新
如果您确实使用 RPC 的 RabbitMQ,那么请记住使用消息 TTL 功能。如果客户端将超时,则将消息过期时间设置为该时间段。这将有助于避免消费者方面的工作浪费,并避免队列在负载下备份。通过消息代理进行 RPC 的一个问题是,一旦队列填满,它可能会增加很长的延迟,需要一段时间才能恢复。将消息过期设置为客户端超时有助于避免这种情况。
关于用于 RPC 的 RabbitMQ。通常我们使用消息代理来实现解耦和持久化。既然RPC是同步通信,就是我们在等待响应,那么耐久性就不用考虑了。这使我们脱钩。问题是,与您可以通过网关或 Docker 服务名称使用 HTTP 进行的解耦相比,解耦是否会给您带来任何好处?
在您的情况下,使用直接 REST 调用应该没问题。
选项 1 使用休息 API :
当你需要同步通信时。比如你的情况。这个选项是合适的。
选项 2 使用 AMQP:
当你需要异步通信时。例如,当您的订单服务创建订单时,您可能希望通知产品服务以减少产品数量。或者您可能想要通知用户服务,用户的订单已成功下单。
在 REST APIs 和基于事件的设计或两者.
之间进行选择完全取决于您的服务的通信行为
你做什么是根据你的要求你可以选择 REST APIs 你看到服务之间的 同步行为
并使用基于事件的设计,你会发现服务需要异步行为,将两者结合起来也没有坏处。
理想情况下,进程间通信协议最好使用消息传递,而客户端服务 REST API 最合适。
检查 microservices.io
中的沟通方式
基于 REST 的架构
优势
当您需要同步环境时,Request/Response 很简单,最适合。
更简单的系统,因为没有中间代理
促进编排,即服务可以根据其他服务的响应采取行动。
缺点
服务需要发现服务实例的位置。
服务之间的一对一映射。
Rest 使用 HTTP,它是建立在 TCP/IP 之上的通用协议,在使用它传递消息时会增加大量开销。
事件驱动架构
优势
事件驱动架构对 API 开发人员很有吸引力,因为它们在异步环境中运行良好。
松散耦合,因为它解耦服务,因为一次服务多个服务可以根据应用程序要求采取行动。很容易将任何新的消费者插入生产者。
提高了可用性,因为消息代理会缓冲消息,直到消费者能够处理它们。
缺点
- 消息代理的额外复杂性,必须具有高可用性
- 调试事件请求并不是那么容易。
我正在处理微服务之间的通信。
例如(虚构的例子,仅供说明):
- 微服务 A - 存储用户(getUser 等)
- 微服务 B - 商店订单(createOrder 等)
现在如果我想从客户端应用添加新订单,我需要知道用户地址。所以请求会是这样的:
客户端 -> 微服务 B(为 userId 5 创建订单)-> 微服务 A(getUser with id 5)
微服务 B 将使用来自用户微服务的详细信息(地址)创建订单。
要解决的问题:如何有效地处理微服务 A 和微服务 B 之间的通信,因为我们必须等到响应返回?
选项:
- 使用 RestAPI,
- 使用 AMQP,比如 RabbitMQ,并通过 RPC 处理这个问题。 (https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html)
我不知道什么对性能更好。通过 RabbitMQ 或 RestAPI 调用速度更快吗? 微服务架构的最佳解决方案是什么?
就我个人而言,我不喜欢为 RPC 使用消息代理。它增加了不必要的复杂性和开销。
如何在用户 Web 服务中托管长期存在的 RabbitMQ 消费者?如果你把它做成一些静态单例,在你的网络服务中你如何处理缩放和并发?或者你让它成为一个独立的守护进程?现在您有两个用户应用程序而不是一个。如果您的用户消费者速度变慢会发生什么,当它使用请求消息时订单服务上下文可能已经超时并发送另一条消息或放弃。
对于 RPC,我建议使用简单的 HTTP。
有一种涉及消息代理的模式可以避免同步网络调用的需要。该模式用于服务使用来自其他服务的事件并将该数据本地存储在自己的数据库中。然后当订单服务需要用户记录时,它可以从自己的数据库访问它。
在您的情况下,您的用户应用程序不需要了解有关订单的任何信息,但您的订单应用程序需要了解有关您的用户的一些详细信息。因此,每次添加、修改、删除用户等时,用户服务都会发出一个事件(UserCreated、UserModified、UserRemoved)。 Orders 服务可以订阅这些事件并仅存储它需要的数据,例如用户地址。
好处是在请求时,您的订单服务对另一服务的同步依赖性较低。测试服务更容易,因为您的请求时间依赖性更少。然而,也存在一些缺点,例如用户记录更改发生和订单应用程序接收之间的一些延迟。需要考虑的事情。
更新 如果您确实使用 RPC 的 RabbitMQ,那么请记住使用消息 TTL 功能。如果客户端将超时,则将消息过期时间设置为该时间段。这将有助于避免消费者方面的工作浪费,并避免队列在负载下备份。通过消息代理进行 RPC 的一个问题是,一旦队列填满,它可能会增加很长的延迟,需要一段时间才能恢复。将消息过期设置为客户端超时有助于避免这种情况。
关于用于 RPC 的 RabbitMQ。通常我们使用消息代理来实现解耦和持久化。既然RPC是同步通信,就是我们在等待响应,那么耐久性就不用考虑了。这使我们脱钩。问题是,与您可以通过网关或 Docker 服务名称使用 HTTP 进行的解耦相比,解耦是否会给您带来任何好处?
在您的情况下,使用直接 REST 调用应该没问题。
选项 1 使用休息 API :
当你需要同步通信时。比如你的情况。这个选项是合适的。
选项 2 使用 AMQP:
当你需要异步通信时。例如,当您的订单服务创建订单时,您可能希望通知产品服务以减少产品数量。或者您可能想要通知用户服务,用户的订单已成功下单。
在 REST APIs 和基于事件的设计或两者.
之间进行选择完全取决于您的服务的通信行为你做什么是根据你的要求你可以选择 REST APIs 你看到服务之间的 同步行为 并使用基于事件的设计,你会发现服务需要异步行为,将两者结合起来也没有坏处。
理想情况下,进程间通信协议最好使用消息传递,而客户端服务 REST API 最合适。 检查 microservices.io
中的沟通方式基于 REST 的架构
优势
-
当您需要同步环境时,
Request/Response 很简单,最适合。
更简单的系统,因为没有中间代理
促进编排,即服务可以根据其他服务的响应采取行动。
缺点
服务需要发现服务实例的位置。
服务之间的一对一映射。
Rest 使用 HTTP,它是建立在 TCP/IP 之上的通用协议,在使用它传递消息时会增加大量开销。
事件驱动架构
优势
事件驱动架构对 API 开发人员很有吸引力,因为它们在异步环境中运行良好。
松散耦合,因为它解耦服务,因为一次服务多个服务可以根据应用程序要求采取行动。很容易将任何新的消费者插入生产者。
提高了可用性,因为消息代理会缓冲消息,直到消费者能够处理它们。
缺点
- 消息代理的额外复杂性,必须具有高可用性
- 调试事件请求并不是那么容易。