内部消息队列与外部消息队列

Internal Message Queue vs External Message Queue

我目前正在使用节点和 python 开发微服务系统。 我们目前正在使用 AWS SQS 来处理队列上服务之间的消息,但是在我们向队列发送消息的其中一项服务中,同一服务处理该消息。没有其他微服务处理它。所以我的问题是,是通过同一应用程序或容器内的事件 bus/event 队列处理内部消息更好,还是应该通过网络请求将消息发送到外部服务并由工作人员处理。

  1. 内部案例 集装箱
Application
|-------------------------------------------------------|
|                                                       |
|  |---------|         Send Message          |---------||
|  | Main    |------------------------------>| Internal||
|  |  App    |<------------------------------| Queue   ||
|  |---------|         Emit Message          |---------||
|                                                       |
|-------------------------------------------------------|
  1. 外部队列
Application
|-----------------|
|                 |
|                 |     Send Network Message  |---------|
|                 |-------------------------->| External|
|                 |<--------------------------| Queue   |
|                 |   Process Network Message |---------|
|                 |                                      
|-----------------|

在做出决定之前,我会考虑几个方面:

  • 考虑到内部队列,如果整个 pod/box 崩溃(无论出于何种原因)会发生什么情况?从业务和体系结构的角度来看,丢失存储在该队列中的消息是可以接受的吗?
  • 延迟是您数据处理工作流程中的一个重要因素吗?如果是,那么使用内部队列可能是一个选项,因为您不会 off-process 处理数据。如果不是,并且数据一致性更重要,那么外部队列可能是可行的方法。
  • 从可伸缩性的角度来看,如果内部队列变得太大怎么办?最终它可能会填满 box/pod 上的内存,但您也可能希望使用其他工作人员将处理延迟保持在某些阈值内(因此您仍然可能最终会退出进程)。
  • 此外,假设您从队列中消费的进程崩溃(出于某种原因),或者它有一个逻辑错误,但队列中仍然有数据,重放它可能具有挑战性,因为队列与应用程序在同一进程中。使用外部队列,您只需插入一个新的工作消费者,它可能位于不同的盒子上。
  • 从可观察性的角度来看(消息数量 consumed/sent/in-flight 等),使用外部队列比自己管理所有这些东西要好得多。

TL;DR - 如果您有延迟限制并且队列用于保留少量快速消耗的消息,那么使用内部队列可能是有意义的。否则,(考虑到上述情况),外部队列是更好的选择。