如果其中一项失败,您如何设计更新多个微服务的软件?


12

我是否可以使用设计模式或实践来帮助出现故障或停机的服务,而其他服务却保持稳定?

如果我有三个微服务,其中两个很好,又在POST中间死了怎么办?有两个将获得POST,而一个则不会。我认为我无法进行交易,因为我正在将请求发送给服务。

我该如何设计?我不想在各种数据库中孤立数据。


6
这不是一个简单的问题要解决。我已经看到它实现为服务的队列(最终的一致性),因为很可能您无法控制服务,并且强加事务管理器或事务功能充其量是最好的选择,而且可能不是一个好主意在SOA环境中。我主要在移动推送中看到过这种情况,无论您是否连接到目的地。
迈克,

微服务上的酸是一个难以克服的难题,另一种选择可能是各种总线,使用redis发布/订阅或队列设计并从入站通道发布一次,然后您的订阅服务或服务代理将目标推向目标并报告成功失败。您将需要监视故障,并为此做好准备。您也可能会遇到失败,其中该事务在一项服务上无效,而在另外两项服务上有效,而这只是您需要解决的另一项失败流程。
蒂姆·塞德奎斯特

我是否会使用“队列管理器”之类的东西,而我猜这是Redis的瓶颈吗?或者至少也有很高的潜力?除了您所描述的,我无所不知。
约翰尼

根据数据流的大小,我实现了一个队列管理器,该队列管理器重试传输,直到报告成功或它发布失败的通知并发送有关中断的SMS警报。我猜这也将取决于预期的中断时间(多长时间)。
htm11h

这是像Rabbitmq一样的东西吗?
约翰尼

Answers:


9

一些选择。

使用持续的沟通渠道

将消息放在高可用性且持久的队列中,而不是HTTP。例如卡夫卡。只要目标服务器在某个时候可用,它就会收到消息。

您现在需要权衡配置和管理复杂子系统(队列)。因此,请确保您分析这是否值得。

退避并重试

让呼叫者保留失败的请求(可能持久保存到磁盘)并定期重试。在这种情况下,区分导致崩溃的请求和刚刚关闭的服务很重要。前者可能是由于错误所致,应予以记录...重试在进行修复之前可能不会有所作为。

检测并补偿

定期任务检查微服务之间的一致性条件。例如,故障会一直记录到必要的直接API查询。如果发现问题(例如有订单但运输从未收到装箱单),请执行赔偿步骤。这些步骤可能是为手动修复创建支持票证,或者向某人发送电子邮件,等等。

考虑设计方案

这样的情况可能需要API网关来管理对受影响的微服务的调用。这样,您可以控制使用哪些策略来减轻此问题。您可能不想让客户负担这些实施细节。请参阅断路器模式

由于微服务是独立的,因此总会存在一些故障情况,可能导致不一致。当这些情况出现时,您必须准备进行手动修复。

如果您需要强一致性,那么微服务将不是一个很好的选择。如果仍然需要可伸缩性,则可能需要研究分片,其中相关数据可以共存于同一分片上,以确保一致性。您仍然可以通过添加分片来扩展IO。

如果您需要强大的一致性并且没有可伸缩性问题,则只需使用单片服务。将库用作应用程序中的边界以分离关注点。


这是RabbitMQ的目的吗?
约翰尼

RabbitMQ是您问题的答案吗?不会。它可能是满足您需求的解决方案的一部分,但它并不能单独解决您的问题。
Kasey Speakman

请注意。我认为RabbitMQ不会保留消息。它已被消耗并从队列中删除,所以不可以。如果您需要持久性并重试,RabbitMQ将无济于事。
2015年

2

我认为您所描述的是共识问题:除非分布式事务中的每个参与者都说操作成功,否则您不想提交。对此的简单解决方案是两阶段提交。从本质上讲,它在每个系统中分阶段进行事务,直到每个系统都报告分阶段成功为止(阶段1)。如果交易中的每个参与者都返回成功,则每个参与者都被要求提交;如果其中任何一个返回了故障,则发出回滚(阶段2)。这种折衷使您获得更复杂的“三相提交”解决方案。您可以在此处阅读每个说明的更好描述:

http://the-paper-trail.org/blog/consensus-protocols-two-phase-commit/

http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.