-1

如果我有一个 Azure 主题,并且对于添加到该主题的每个 X 类型的事件,我需要有一个订阅者将该事件记录到一个位置,并且我有另一个订阅者实际上对该主题消息进行一些处理。

在几分钟内处理我的审计或处理订阅者失败并确保我不会错过任何主题消息并创建数据损坏场景的正确设计是什么?

我可以运行每个实例的三个版本,然后这三个版本不太可能同时关闭,但这不是一个完美的场景。有什么其他选择呢?作为 API 的一部分,我是否遗漏了一些东西?

4

1 回答 1

1

我可能不理解你试图解决的失败。如果我正确理解您的情况,您有一个审计订阅和一个处理订阅都订阅和“事件主题”。这意味着您将有两个逻辑消费者:一个用于审计,一个用于处理(我说是逻辑的,因为每个消费者可以有多个实例从同一个订阅读取吞吐量和冗余)。

如果您在订阅客户端上使用 PeekLock(默认)作为接收模式,这意味着如果您的消费者在记录审计消息或处理事件时出现故障或异常,该消息最终将重新出现以由另一个消费者处理实例。这假定由于异常未调用 Complete。从理论上讲,如果您的审计和处理消费者正在执行幂等操作,那么即使您的消费者失败,他们也可以在重新上线时赶上,并且不会丢失任何消息,尽管有些消息可能会被多次接收。如果您按照上面的建议运行每个使用者的多个实例,这不会改变。让每个消费者运行多个实例确实减少了可能的停机时间,但你不应该 即使您有单个实例处理,也不会错过任何消息。订阅将保留它们,直到消费者备份。

如果您使用 RecieveAndDelete 接收模式,那么您有可能丢失消息。这是一篇关于使用 Service Bus Brokered Messaging 提高性能的最佳实践的精彩文章。通读这个。

根据审计和处理操作的资源密集程度,有各种部署选项。您可以有一个工作人员角色或进程,将不同线程上的审计和处理消息作为一对处理并部署多个实例。这意味着每个实例都可以处理这两种类型的消息,但是如果其中一台机器停止运行,另一个正在运行的实例可以继续处理,因此存在冗余。

您需要检查死信消息(例如毒消息)以及那些消息未处理或可能未完全处理。

现在,您确实提到了数据损坏,所以我假设您的意思是审计日志被写入的可能性,但实际事件无法处理。这有点棘手。这是您试图结合的两个不同的操作。简单的答案是你不能保证这不会不同步。这两个操作之间没有事务(您也不希望存在于分布式系统中)。将审计视为执行操作的意图,而不是操作实际完成。您不能仅仅因为向系统提供了消息就假设处理将成功完成。一旦处理发生,它可以记录操作实际上已完成。或者,它可能会发出一条信息让另一位审计员记录下来。这将为您提供一个更好的指标来分析您的系统:请求的操作数与实际完成的操作数。在一段时间内查看时,该指标可以为您提供系统的实际成功吞吐量。

于 2013-09-15T15:12:52.233 回答