You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure服务总线队列消费者序列号与生产者及门户返回值不一致问题

问题原因

该现象是Azure Service Bus的固有设计,并非代码逻辑错误:
调用ScheduleMessageAsync()返回的序列号是定时调度任务专属序列号,仅用于标识待触发的定时调度任务,此时消息尚未正式写入队列存储。当到达你设置的入队时间时,Service Bus会将消息正式写入队列,此时会给消息重新分配一个全局唯一的队列消息序列号,也就是消费者侧通过args.Message.SequenceNumber拿到的值,二者天然不相等。

解决方案

方案1:使用自定义属性关联(推荐)

在生产者发送消息时,主动添加全局唯一的自定义属性作为关联标识,存入数据库的同时写入消息属性,消费者侧读取该属性匹配数据库记录即可。
修改后的生产者代码:

public async Task<Guid> SendMessage(string messageBody, DateTimeOffset scheduledEnqueueTimeUtc)
{
    await using (ServiceBusClient client = new ServiceBusClient(_config["ServiceBus:Connection"]))
    {
        ServiceBusSender sender = client.CreateSender(_config["ServiceBus:Queue"]);
        ServiceBusMessage message = new ServiceBusMessage(messageBody);
        // 生成自定义唯一标识
        var customMsgId = Guid.NewGuid();
        // 写入消息自定义属性
        message.ApplicationProperties["CustomMessageId"] = customMsgId.ToString();
        // 调度消息
        await sender.ScheduleMessageAsync(message, scheduledEnqueueTimeUtc);
        // 返回自定义标识存入数据库
        return customMsgId;
    }
}

消费者侧读取属性匹配:

private async Task MessageHandler(ProcessMessageEventArgs args)
{
    string body = args.Message.Body.ToString();
    JObject jsonObject = JObject.Parse(body);
    var eventStatus = (string)jsonObject["EventStatus"];
    // 读取自定义标识查询数据库
    var customMsgId = args.Message.ApplicationProperties["CustomMessageId"].ToString();
    // 后续逻辑用customMsgId匹配数据库记录即可

    await args.CompleteMessageAsync(args.Message);
    int result = await dbContext.SaveChangesAsync();
}

方案2:使用调度序列号匹配

如果不想新增自定义属性,可以直接在消费者侧读取ScheduledEnqueueSequenceNumber属性,该值和生产者调用ScheduleMessageAsync()返回的序列号完全一致:

private async Task MessageHandler(ProcessMessageEventArgs args)
{
    string body = args.Message.Body.ToString();
    JObject jsonObject = JObject.Parse(body);
    var eventStatus = (string)jsonObject["EventStatus"];
    // 读取调度序列号,和你之前存入数据库的序列号匹配
    long scheduledSequenceNumber = args.Message.ScheduledEnqueueSequenceNumber;

    await args.CompleteMessageAsync(args.Message);
    int result = await dbContext.SaveChangesAsync();
}

内容的提问来源于stack exchange,提问作者chuckd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 10:24:01