使用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
相关产品推荐
相关产品推荐

