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

Azure Service Bus队列发送代码内存泄漏及实例化问题咨询

回答

你的代码不会直接引发内存泄漏,但存在严重的性能缺陷和资源浪费问题,ServiceBusClient的实例化逻辑确实应该放到类构造函数中做复用。


现有代码的问题说明

  • 内存泄漏层面:你在方法中用await using声明ServiceBusClient,方法执行完成后会按逻辑释放该对象持有的所有资源,不会出现资源无法回收导致的内存泄漏。
  • 性能层面:ServiceBusClient是官方明确建议单例复用的重量级对象,它内部维护了AMQP连接池、TCP长连接、链路鉴权缓存等核心资源,每次发消息都新建、释放Client的开销极高,高并发场景下会直接导致本地临时端口耗尽、服务端连接数超限、消息发送延迟飙升甚至请求超时,属于典型的反模式实现。
  • 代码逻辑层面:你在Startup中注册了IAzureQueueService的瞬态服务,但业务代码完全没有走DI容器,而是手动new AzureQueueService(config)实例化对象,之前的服务注册代码完全不生效,还额外增加了维护成本;另外类中定义的静态azureServiceBusString字段没有实际作用,静态字段会被所有类实例共享,每次构造函数重复赋值属于冗余逻辑。

推荐实现方案

  • 调整AzureQueueService实现,将ServiceBusClient放到构造函数初始化,同时缓存不同队列对应的ServiceBusSender(Sender同样是线程安全的可复用对象),并实现异步释放接口:
public class AzureQueueService : IAzureQueueService, IAsyncDisposable
{
    private readonly ServiceBusClient _serviceBusClient;
    private readonly ConcurrentDictionary<string, ServiceBusSender> _senderCache = new();

    public AzureQueueService(IConfiguration config)
    {
        // 从配置读取连接字符串,不要硬编码
        var connString = config.GetConnectionString("AzureServiceBus");
        _serviceBusClient = new ServiceBusClient(connString);
    }

    public async Task SendMessageAsync<T>(T serviceBusMessage, string queueName)
    {
        var sender = _senderCache.GetOrAdd(queueName, qName => _serviceBusClient.CreateSender(qName));
        string messageBody = JsonSerializer.Serialize(serviceBusMessage);
        var message = new ServiceBusMessage(Encoding.UTF8.GetBytes(messageBody));
        await sender.SendMessageAsync(message);
    }

    public async ValueTask DisposeAsync()
    {
        foreach (var sender in _senderCache.Values)
        {
            await sender.DisposeAsync();
        }
        await _serviceBusClient.DisposeAsync();
    }
}
  • 调整服务注册生命周期,将服务注册为单例,和ServiceBusClient的复用要求匹配:
services.AddSingleton<IAzureQueueService, Core.Services.AzureQueueService>();
  • 业务代码中不要手动实例化AzureQueueService,直接通过DI注入IAzureQueueService实例调用方法即可。

注:这是Azure Service Bus官方推荐的标准用法,复用Client和Sender可以把消息发送的吞吐量提升数倍,同时避免连接相关的故障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:48:20