【问题标题】:How to handle in Event Driven Microservices if the messaging queue is down?如果消息队列已关闭,如何在事件驱动微服务中进行处理?
【发布时间】:2018-11-06 09:31:48
【问题描述】:

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

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

A'M'B

问题是如果代理 M 宕机了怎么办?

我能想到的可能解决方案: 定期从服务 A ping 以检查消息队列 M 是否已关闭。同时,服务A 将数据存储在本地数据库中,并在代理 M 启动后将其转储到队列中。

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

【问题讨论】:

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


    【解决方案1】:

    问题是如果代理 M 宕机了怎么办?

    如果 broker 宕机,那么 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 直接相互通信,而不是通过中介。

    至于这种事情最好由线程还是反应式编程来处理,这是个人喜好问题——我个人更喜欢反应式编程,因为多线程风格通常意味着阻塞-RPC-操作,以及在阻塞操作中被阻塞的线程是一个冻结/无助的线程,直到远程方响应(例如,如果 M 需要 2 分钟来响应 RPC 请求,那么 A 对 M 的 RPC 调用在 2 分钟内无法返回,这意味着调用线程在 2 分钟内根本无法执行任何操作)。在反应式方法中,如果 A 的线程愿意,那么在这 2 分钟期间,A 的线程还可以在此期间做其他事情(例如 ping M 以确保它没问题,或联系备份代理等)。

    【讨论】:

    • 感谢 Jeremy 的深思熟虑的回答。只是要知道 RX Java 类似于多线程但它是非阻塞的?如果是这样,RX 将是最好的选择?
    • 我没用过RX,所以无法评论;您需要自行决定哪些 API 最适合您的需求。
    猜你喜欢
    • 2019-10-21
    • 1970-01-01
    • 2019-11-26
    • 2020-01-31
    • 1970-01-01
    • 2011-01-28
    • 2018-09-02
    • 1970-01-01
    • 2019-12-31
    相关资源
    最近更新 更多