multithreading - 如果消息队列关闭,如何在事件驱动微服务中处理?

标签 multithreading reactive-programming message-queue microservices event-driven-design

假设微服务环境中有两个服务AB

在 A 和 B 之间有一个消息队列 M,它是一个代理。

A<---->'M'<----->B

问题是如果经纪人 M 宕机了怎么办?

我能想到的可能的解决方案: 定期从服务 A 进行 Ping,以检查消息队列 M(只要它已关闭)。与此同时,服务A 将数据存储在本地数据库中,并在代理 M 启动后将其转储到队列中。

考虑到上述问题,如果有人可以建议线程或响应式(Reactive)编程是否最适合这种情况以及通过代码处理它的方式,我将不胜感激。

最佳答案

The problem is what if the broker M is down?

如果代理关闭,则 A 和 B 无法使用它进行通信。

在这种情况下 A 和 B 应该做什么很大程度上取决于您的特定应用程序/用例的详细信息。

在这种情况下他们可以做一些有用的工作吗?

如果没有,那么他们不妨暂时停止尝试处理任何工作/交易,而只是坐下来等待 M 回来。让他们在这种状态下定期对 M 进行 ping/查询(看看它是否回来了)是个好主意。

如果他们可以在这种情况下做一些有用的事情,那么你可以让他们继续以某种“离线模式”工作,在本地缓存他们的结果,以期待 M 在未来某个时候重新出现。当然,这可能会成为问题,特别是如果 M 很长一段时间没有恢复——例如

  • 如果缓存的本地结果集变得不合理地大,导致 A/B 没有空间来存储它怎么办?
  • 或者,如果 A 和 B 缓存本地结果,这些结果都将应用于 M 中的相同数据结构,这样当 M 重新上线时,A 的某些结果将覆盖 B 的结果(反之亦然,具体取决于他们重新连接的顺序)? (这类似于在几个开发人员离线工作后源代码控制服务器必须处理的事情,他们都对同一文件中的相同行进行更改,然后他们都返回在线并想要将更改提交到该文件。它可能会有点复杂,并且并不总是有明显的“正确”方法来解决冲突)
  • 最后,如果是 A 或 B “说”了什么导致 M 崩溃怎么办?在这种情况下,在 M 重新上线后将相同的请求重新上传到 M 可能只会导致它再次崩溃,如此无限循环,使服务永远无法使用。 (当然,在这种情况下,正确的修复方法是调试 M)

另一种方法可能是通过拥有多个冗余代理(例如 M1、M2、M3...)来尝试避免该问题,这样只要其中至少一个仍然可用,生产性工作就可以继续。或者也许允许 A 和 B 直接相互通信,而不是通过中介。

至于这种事情最好通过线程还是响应式(Reactive)编程来处理,这是个人喜好的问题——我个人更喜欢响应式(Reactive)编程,因为多线程风格通常意味着阻塞 RPC 操作,并且在阻塞操作中被阻塞的线程是卡住/无助的线程,直到远程方响应为止(例如,如果 M 花了 2 分钟来响应 RPC 请求,则 A 对 M 的 RPC 调用在 2 分钟内无法返回,这意味着调用线程在 2 分钟内无法执行任何操作)。在响应式(Reactive)方法中,如果 A 愿意的话,A 的线程还可以在这 2 分钟期间执行其他操作(例如对 M 执行 ping 操作以确保其正常,或联系备份代理等)。

关于multithreading - 如果消息队列关闭,如何在事件驱动微服务中处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50555353/

相关文章:

java - 如何在Android中通过蓝牙处理InputStream和OutputStream

c - C中线程间的全局变量同步

c++ - 浏览器中的多线程 WebAssembly 比单线程慢,为什么?

java - 深入理解Java中的Reactive Programming

c++ - 有没有一种有效的方法来搜索队列中的键并覆盖它的值?

message-queue - 处理数百万条定时(预定)消息的解决方案?

python - 键盘中断与 python 的多处理

javascript - Rx 随机间隔

system.reactive - 响应式(Reactive)框架/DoubleClick

c# - Azure 服务总线中的死信队列中的消息是否会过期?