微服务模式(一):事件处理

我是兽兽,从事云计算的健身萌妹纸,不定期更新5G&IoT内容,更多好货可关注公号:5G物联网世界。 

“事件处理”是一种模型,它允许您通过使用消息队列来解耦您的微服务。虽然消息队列处理没有适合所有人的解决方案,但是这里有一些处理错误和管理事务的好模式,它们将加深您对最佳实践微服务体系结构设计的理解。

“事件处理”是一种模型,它允许您通过使用消息队列来解耦您的微服务。您不是直接连接到某个服务(该服务可能在已知位置,也可能不在),而是通过Redis、Amazon SQS、RabbitMQ、Apache Kafka和整个主机的其他源广播和侦听队列中的事件。

“消息队列”是一个高度分布式和可伸缩的系统。它应该能够处理数百万条消息,这样我们就不必担心它不可用。在队列的另一端,将有一个“使用者”侦听指向它的新消息。当它接收到这样的消息时,它处理该消息,然后将其从队列中删除。

由于事件处理模式的异步特性,需要以可编程的方式处理故障。

事件处理,至少一次交付

第一个基本同步机制是请求交付。我们将消息添加到队列中,然后等待队列的确认(ACK),以让我们知道消息已经收到。当然,我们不知道消息是否已经传递,但是接收ACK应该足以通知用户并继续。

接收服务始终可能无法处理消息。潜在的原因包括直接失败,或者接收服务中的错误,或者添加到队列中的消息没有按照接收服务能够理解的方式进行格式化。我们需要独立处理这两个问题。

处理错误

分布式系统出现问题并不罕见。这是基于微服务的软件设计背后的逻辑的一个重要部分。

在上面的场景中,如果无法处理有效的消息,一种标准方法是重试处理消息,通常会有延迟。重要的是,每当我们无法处理一条消息时,都要附加错误,以便构建出错历史,这可以在事件后分析和重构过程中提供真正有用的见解。这样的历史记录还使我们能够了解我们尝试处理消息的次数,因为在超过这个阈值之后,我们不想继续重试。我们需要将此消息移动到第二个队列或死信队列,我们将在接下来讨论这个队列。重要的是要设置这样的历史生成机制,并在您的微服务体系结构中构建一种处理错误的方法,使其不会阻塞队列或产生级联的下游影响。

使用死信队列调试失败

处理消息之后从队列中删除消息是一种常见的做法。死信队列的目的是为了检查这个队列上的失败消息,以帮助我们调试系统。因为我们可以将错误细节附加到消息主体,所以我们知道错误是什么,并且知道历史记录应该放在哪里。

处理幂等事务

虽然现在许多消息队列除了提供至少一次的传递之外,还提供最多一次的传递,但是在处理大量消息时,后者仍然是最好的选择。为了处理接收服务可能两次获得消息这一事实,该服务需要能够使用自己的逻辑来处理这种重复。确保消息不会被处理两次的常见方法之一是在一个事务表中记录消息ID,记录已经处理的消息,并使用一个参数说明是否将丢弃该消息。

处理消息的排序

在处理重试失败时,常见的问题之一是接收的消息顺序错误或顺序不正确,这会将不一致的数据转储到数据库中。为了避免这种问题的方法之一是利用事务表和存储消息dispatch_date除了ID。当接收服务得到了消息,它不仅可以检查如果当前消息被处理它可以检查最近的消息,如果没有丢弃它。

利用原子事务

这是在将遗留系统转换为微服务时最常见的问题。在存储数据时,数据库可以是原子的——也就是说,所有操作都发生或不发生。分布式事务不能提供与数据库中相同的事务类型。当数据库事务的一部分失败时,我们可以回滚事务的其他部分。通过使用此模式,我们只会在进程成功时从队列中删除消息,以便在出现故障时继续重试。即使事务的初始状态是不完整的,这也会使我们的事务在理想情况下最终变得一致。

不幸的是,没有适合所有人的消息传递解决方案。我们需要定制与服务的操作条件匹配的解决方案。

我将在下一篇文章中继续讨论这个问题,该文章将深入探讨“服务发现”。


分享到:


相關文章: