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