队列宕机怎么办?
What to do when the queue is down?
我有 2 个微服务,A
和 B
。当 A
收到来自用户的请求时,它会被处理(在数据库中存储一些东西)并将消息发送到队列,该队列由 B
.
读取
如果队列挂了,我最初的想法是让整个请求掉线,回滚,并向用户显示错误,要求稍后重试。这是一种不好的做法吗?
将消息存储在标记为 NOT_SENT
的 A
的数据库中,并在队列再次启动时稍后发送作业是否更好?还是过度工程化?
编辑:对 A
的请求需要同步,因此用户知道其结果,但他们 还不需要知道 B
处理消息,所以可以异步。
我觉得这取决于用户是否应该能够根据他们的第一个动作对系统做任何事情,或者他们希望它立即反映在其他地方。
举个例子,因为您通常会在会话中管理此信息而不是写入数据库:如果第一个操作是 "add product to cart" 然后用户继续尝试并结帐,我认为整个请求应该尽早失败,而不是保存一个可以被视为 "false" 的状态,当它稍后失败并且一开始似乎正常工作时。
另一个例子可能是获得某种收据或代码,然后他们想用它们来离线兑换东西,但是负责这样做的人还没有看到代码有效,你又一次遇到了这种情况都认为对方是错误的,因为他们有不同的数据。
现在如果你只是想收集一些数据并在不同的服务中处理它,也许最好将它保存为未发送而不是强迫用户多次发送数据或稍后再回来。
有了关于您的要求或领域的更多详细信息,您可能会对哪个选项是一个好的解决方案做出更有根据的猜测,因为它们解决了不同的问题。
是的,这取决于您的操作是原子操作(因此用户需要立即反馈),还是只是后台处理作业,正如 Nicolas 指出的那样。
我只想补充一点,您可以考虑实施断路器模式,在向用户报告失败之前重试几次,或者根据您的要求将消息保留为 NOT_SENT。
您正在数据库中创建冗余队列。如果您的队列不可靠,您可以创建多个队列,但使用数据库设计您自己的队列是重复工作。如果您确实需要两个队列来实现冗余,请创建两个队列。它可以兼作医院队列,因为可能需要处理来自主队列的处理失败(具有相同的重试语义)。
I have 2 microservices, A and B. When A receives a request from a user, it gets processed (store some things in the database) and a message is sent to a queue that is read by B.
好的。让我们假设一些东西被处理并保存到数据库=产生了一些副作用。
If the queue is down, my initial thought is to make the entire request fall over and show an error to the user asking to try again later. Is it a bad practice?
但是您需要撤消第一步(上面讨论的那个),然后才能使客户的请求失败!您有两个选择:
包装交易中的副作用和队列;这仅适用于可撤消的副作用(即删除文件不可撤消,除非它只是被移至垃圾箱)。当第一步必须同步处理时,应使用此解决方案。
也将请求添加到队列中,稍后处理,第一个异步步骤是微服务 A。如果添加到队列失败,则请求失败。此解决方案比第一个解决方案更具可扩展性。
你问的是关于一个非常抽象的例子的具体问题。在实践中,这样的问题很少产生有用的结果。
也就是说,如果您的系统无法以可靠和确定的方式处理请求(例如,队列组件无法正常运行),那么您应该阻止所有依赖该功能的请求(即使用 503 - 服务不可用)。实际上,这是队列问题还是数据库问题都无关紧要 - 除非所有部分都在运行,否则服务无法执行其行为,因此请提前告诉客户。如果你的可靠性需要更高,你就得在设计上投入更多的时间才能达到更高的可靠性。
我有 2 个微服务,A
和 B
。当 A
收到来自用户的请求时,它会被处理(在数据库中存储一些东西)并将消息发送到队列,该队列由 B
.
如果队列挂了,我最初的想法是让整个请求掉线,回滚,并向用户显示错误,要求稍后重试。这是一种不好的做法吗?
将消息存储在标记为 NOT_SENT
的 A
的数据库中,并在队列再次启动时稍后发送作业是否更好?还是过度工程化?
编辑:对 A
的请求需要同步,因此用户知道其结果,但他们 还不需要知道 B
处理消息,所以可以异步。
我觉得这取决于用户是否应该能够根据他们的第一个动作对系统做任何事情,或者他们希望它立即反映在其他地方。
举个例子,因为您通常会在会话中管理此信息而不是写入数据库:如果第一个操作是 "add product to cart" 然后用户继续尝试并结帐,我认为整个请求应该尽早失败,而不是保存一个可以被视为 "false" 的状态,当它稍后失败并且一开始似乎正常工作时。
另一个例子可能是获得某种收据或代码,然后他们想用它们来离线兑换东西,但是负责这样做的人还没有看到代码有效,你又一次遇到了这种情况都认为对方是错误的,因为他们有不同的数据。
现在如果你只是想收集一些数据并在不同的服务中处理它,也许最好将它保存为未发送而不是强迫用户多次发送数据或稍后再回来。
有了关于您的要求或领域的更多详细信息,您可能会对哪个选项是一个好的解决方案做出更有根据的猜测,因为它们解决了不同的问题。
是的,这取决于您的操作是原子操作(因此用户需要立即反馈),还是只是后台处理作业,正如 Nicolas 指出的那样。 我只想补充一点,您可以考虑实施断路器模式,在向用户报告失败之前重试几次,或者根据您的要求将消息保留为 NOT_SENT。
您正在数据库中创建冗余队列。如果您的队列不可靠,您可以创建多个队列,但使用数据库设计您自己的队列是重复工作。如果您确实需要两个队列来实现冗余,请创建两个队列。它可以兼作医院队列,因为可能需要处理来自主队列的处理失败(具有相同的重试语义)。
I have 2 microservices, A and B. When A receives a request from a user, it gets processed (store some things in the database) and a message is sent to a queue that is read by B.
好的。让我们假设一些东西被处理并保存到数据库=产生了一些副作用。
If the queue is down, my initial thought is to make the entire request fall over and show an error to the user asking to try again later. Is it a bad practice?
但是您需要撤消第一步(上面讨论的那个),然后才能使客户的请求失败!您有两个选择:
包装交易中的副作用和队列;这仅适用于可撤消的副作用(即删除文件不可撤消,除非它只是被移至垃圾箱)。当第一步必须同步处理时,应使用此解决方案。
也将请求添加到队列中,稍后处理,第一个异步步骤是微服务 A。如果添加到队列失败,则请求失败。此解决方案比第一个解决方案更具可扩展性。
你问的是关于一个非常抽象的例子的具体问题。在实践中,这样的问题很少产生有用的结果。
也就是说,如果您的系统无法以可靠和确定的方式处理请求(例如,队列组件无法正常运行),那么您应该阻止所有依赖该功能的请求(即使用 503 - 服务不可用)。实际上,这是队列问题还是数据库问题都无关紧要 - 除非所有部分都在运行,否则服务无法执行其行为,因此请提前告诉客户。如果你的可靠性需要更高,你就得在设计上投入更多的时间才能达到更高的可靠性。