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

使用Service Bus会话仍无法保证消息FIFO投递,求排查问题

问题:Service Bus主题会话模式下消息接收顺序与发布不一致

我为Service Bus主题配置了一个发布者和一个消费者,目标是让消费者按照发布者的消息发布顺序接收消息。以下是发布消息的代码:

public void Publish<T>(T messageObject)
{
    var jsonString = JsonSerializer.Serialize(messageObject);
    var message = new ServiceBusMessage(jsonString)
            {
                SessionId = "12345"
            };
    
    message.ApplicationProperties["messageType"] = typeof(T).Name;

    serviceBusSender.SendMessageAsync(message);
}

接收端代码如下:

public async Task ReceiveWithSessionsAsync()
{
    var options = new ServiceBusSessionProcessorOptions
    {
        ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete,
        AutoCompleteMessages = true,
        MaxConcurrentSessions = 1,
        MaxConcurrentCallsPerSession = 1,
    };

    await using ServiceBusSessionProcessor processor = serviceBusClient.CreateSessionProcessor("my_topic", "my_subscription__session_enabled", options);

    processor.ProcessMessageAsync += MessageHandler;

    async Task MessageHandler(ProcessSessionMessageEventArgs args)
    {
        var body = args.Message.Body.ToString();
        logger.LogInformation($"received body: {body}");
    }

    // start processing
    await processor.StartProcessingAsync();
}

多次调用Publish方法发布消息,再调用ReceiveWithSessionsAsync方法接收,但消息接收顺序仍与发布顺序不一致。请问遗漏了什么?


问题分析与解决

核心问题出在发布端未保证异步发送的顺序执行,具体如下:

  • 发布方法未等待异步发送完成
    你的Publish是同步方法,但内部调用SendMessageAsync时没有用await等待操作完成。这会导致每次调用Publish时,消息发送是后台异步执行的,多个并发的发送操作可能乱序完成,最终Service Bus接收消息的顺序会和你调用Publish的顺序不一致。

    修正方式是将Publish改为异步方法,并等待发送完成:

    public async Task Publish<T>(T messageObject)
    {
        var jsonString = JsonSerializer.Serialize(messageObject);
        var message = new ServiceBusMessage(jsonString)
                {
                    SessionId = "12345"
                };
        
        message.ApplicationProperties["messageType"] = typeof(T).Name;
    
        await serviceBusSender.SendMessageAsync(message);
    }
    

    调用Publish时也必须使用await,确保前一条消息发送完成后再发送下一条:

    await Publish(message1);
    await Publish(message2);
    await Publish(message3);
    
  • 额外确认项
    你的接收端配置MaxConcurrentSessions=1和MaxConcurrentCallsPerSession=1是正确的,这保证了同一会话内的消息会被串行处理。只要发布端保证了消息发送顺序,接收端就能按发布顺序接收。同时要确认订阅确实已启用会话功能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:45:49