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

.NET Core 3.1中Azure Service Bus:单Sender处理数千消息是否更优?

Azure Service Bus Sender 复用建议:单实例复用优于每条消息新建

结论:必须复用单个ServiceBusSender实例,别给每条消息都新建Sender

为啥不能每次新建?

  • 性能浪费:每次创建Sender都会触发初始化逻辑,哪怕ServiceBusClient是单例,底层连接池能复用连接,但Sender本身的创建销毁还是会产生额外开销,几千请求下来,这个损耗会很明显,拖慢发送吞吐量。
  • 资源配额风险:Azure Service Bus有连接数限制,频繁创建Sender会快速消耗连接配额,容易触发限流或报错。
  • SDK设计就是让你复用的:ServiceBusSender是线程安全的,完全支持多并发场景下重复调用发送接口,官方设计初衷就是鼓励复用实例。

你当前代码的问题

现在的实现每条消息都创建并销毁Sender,在高并发场景下会导致不必要的资源消耗,发送效率上不去,甚至可能触发Service Bus的限流机制。

优化后的代码示例

利用ConcurrentDictionary缓存每个topic/queue对应的Sender,确保每个topic只创建一次Sender:

private readonly ConcurrentDictionary<string, ServiceBusSender> _senderCache = new ConcurrentDictionary<string, ServiceBusSender>();
private readonly ServiceBusClient _serviceBusClient;
private readonly ILogger _logger;

public YourServiceClass(ServiceBusClient serviceBusClient, ILogger<YourServiceClass> logger)
{
    _serviceBusClient = serviceBusClient;
    _logger = logger;
}

private async Task EnqueueAsync(ServiceBusMessage message, string queueOrTopicName)
{
    // 从缓存拿Sender,没有就创建
    var sender = _senderCache.GetOrAdd(queueOrTopicName, _serviceBusClient.CreateSender);
    
    try
    {
        await sender.SendMessageAsync(message);
        _logger.LogInformation($"Message published to {queueOrTopicName}");
    }
    catch (ServiceBusException ex)
    {
        _logger.LogError(ex, $"Failed to publish message to {queueOrTopicName}: {ex.Message}");
        throw new QueueException("Unable to publish data.");
    }
}

额外提示

  • 不用手动销毁Sender,因为ServiceBusSender的生命周期和单例的ServiceBusClient绑定,当ServiceBusClient被DI容器释放时,所有关联的Sender会自动清理。
  • 如果要处理大量消息,推荐用SendMessagesAsync批量发送,减少网络往返次数,进一步提升性能。
  • 你这个场景里topic只有5个订阅,完全不用担心缓存膨胀,直接永久缓存Sender就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:02:29