Azure Service Bus主题订阅故障定位及重复消息处理规避咨询
一、定位故障订阅
Azure Service Bus中每个主题订阅都有独立的死信队列(DLQ),消息只会被移至对应故障订阅的专属DLQ,你可以通过以下方式快速定位:
- 查看DLQ归属路径:订阅的DLQ命名规则为
{主题名}/Subscriptions/{订阅名}/$DeadLetterQueue,从DLQ的完整路径可直接识别对应的订阅。 - 读取死信消息的
DeadLetterSource属性:每条死信消息都会携带DeadLetterSource属性,其值为故障订阅的完整路径(如my-topic/Subscriptions/faulty-sub),直接查看该属性即可定位。 - 监控订阅指标:在Azure Portal中查看主题下各订阅的指标:
- 重点关注
DeadLetterMessagesCount:数值上升的订阅即为故障源; - 辅助查看
DeliveryCount(消息投递次数)、ActiveMessagesCount(未处理消息数),异常波动的订阅大概率存在处理故障。
- 重点关注
- 检查处理程序日志:如果订阅的消费程序有日志记录,排查对应时间点的错误日志,直接定位故障订阅和具体原因。
二、重新处理时避免已成功订阅重复处理
核心是跟踪消息的处理状态,确保每个订阅仅处理一次,可采用以下方案:
- 在消息属性中记录已处理订阅:
从DLQ取出消息后,在消息的UserProperties中添加ProcessedSubscriptions集合,记录所有已成功处理该消息的订阅名称。重新投递消息到主题后,每个订阅的处理程序先检查该属性:若自身订阅名在列表中,直接跳过处理;若不在,则执行处理逻辑,成功后将自己的订阅名加入列表并更新消息属性。 - 使用幂等键做处理校验:
每个订阅处理消息时,生成由MessageId(或业务唯一标识)+ 订阅名组成的幂等键,将该键存储到外部持久化存储(如Redis、Azure Table Storage)。处理前先查询该键是否存在:存在则跳过处理;不存在则执行处理,成功后写入该键。 - 定向重发至故障订阅:
若已明确故障订阅,无需将消息发回原主题,直接通过Service Bus SDK的Transfer操作,将死信消息转移到故障订阅的活动队列。这样其他已成功处理的订阅不会再次收到这条消息,仅故障订阅会重新处理。 - 利用会话状态(会话场景适用):
若主题启用了会话功能,可将消息关联到会话,在会话状态中记录已处理的订阅列表。订阅处理程序读取会话状态后,判断自身是否已处理,再决定是否执行逻辑。
内容的提问来源于stack exchange,提问作者user2408073
相关产品推荐
相关产品推荐

