MassTransit服务器端出现IServiceProvider已释放异常,本地运行正常
问题:MassTransit应用服务器环境报IServiceProvider已释放异常,本地运行正常
异常堆栈
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'IServiceProvider'. at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at MassTransit.Configuration.RegistrationContext.GetService(Type serviceType) in /_/src/MassTransit/DependencyInjection/Configuration/RegistrationContext.cs:line 133 at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.CreateScope(IServiceProvider provider) at MassTransit.DependencyInjection.BaseConsumeScopeProvider.GetScopeContext[TScopeContext,TPipeContext](TPipeContext context, Func`4 existingScopeContextFactory, Func`4 createdScopeContextFactory, Func`4 pipeContextFactory) in /_/src/MassTransit/DependencyInjection/DependencyInjection/BaseConsumeScopeProvider.cs:line 40 at MassTransit.DependencyInjection.ConsumeScopeProvider.GetScope[TConsumer,T](ConsumeContext`1 context) in /_/src/MassTransit/DependencyInjection/DependencyInjection/ConsumeScopeProvider.cs:line 43 at MassTransit.DependencyInjection.ScopeConsumerFactory`1.Send[TMessage](ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/DependencyInjection/DependencyInjection/ScopeConsumerFactory.cs:line 20 at MassTransit.Middleware.ConsumerMessageFilter`2.MassTransit.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Middleware/ConsumerMessageFilter.cs:line 48 at MassTransit.Middleware.ConsumerMessageFilter`2.MassTransit.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Middleware/ConsumerMessageFilter.cs:line 73 at MassTransit.Middleware.TransactionFilter`1.Send(T context, IPipe`1 next) in /_/src/MassTransit/Middleware/TransactionFilter.cs:line 48 at MassTransit.Middleware.RetryFilter`1.MassTransit.IFilter<TContext>.Send(TContext context, IPipe`1 next) in /_/src/MassTransit/Middleware/RetryFilter.cs:line 47
问题背景
- 本地环境运行无异常,仅服务器环境触发该错误
- 初始异常出现在自定义Dapper仓储,改用DapperIntegration库后问题仍存在
- 基于RabbitMQ配置,包含Saga状态机、重试机制、事务过滤器
配置代码
public static void ConfigureMassTransit(IServiceCollection services, RabbitMqConfiguration rabbitConfig, RabbitMqQueueConfiguration queueConfig, string sagaConnectionString) { services.AddMassTransit(x => { x.AddConsumers(Assembly.GetExecutingAssembly()); var entryAssembly = System.Reflection.Assembly.GetEntryAssembly(); x.AddSagaStateMachine<CaseSagaStateMachine, CaseSagaState>() .DapperRepository(sagaConnectionString) .Endpoint(e => { e.Name = queueConfig.CaseServiceBus; }); x.UsingRabbitMq((context, cfg) => { cfg.Host(new Uri($"rabbitmq://{rabbitConfig.Host}/{rabbitConfig.VirtualHost}"), host => { host.Username(rabbitConfig.UserName); host.Password(rabbitConfig.Password); }); cfg.ReceiveEndpoint(queueConfig.CaseServiceBus, endPoint => //replace with our created queue { endPoint.UseMessageRetry(retry => { retry.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromMinutes(t)).ToArray()); }); endPoint.UseTransaction(x => { x.Timeout = TimeSpan.FromSeconds(90); x.IsolationLevel = IsolationLevel.ReadCommitted; }); //endPoint.UseInlineFilter(async (context, next) => //{ // var transactionOptions = new TransactionOptions // { // Timeout = TimeSpan.FromSeconds(120), // IsolationLevel = IsolationLevel.ReadUncommitted, // }; // using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions, TransactionScopeAsyncFlowOption.Enabled)) // { // await next.Send(context).ConfigureAwait(false); // scope.Complete(); // } //}); endPoint.ConfigureSagas(context); endPoint.ConfigureConsumers(context); }); cfg.PrefetchCount = 10; }); }); services.Configure<MassTransitHostOptions>(options => { options.WaitUntilStarted = true; options.StartTimeout = TimeSpan.FromSeconds(30); options.StopTimeout = TimeSpan.FromMinutes(1); }); services.AddSingleton<IHostedService, BusService>(); }
解决方案
1. 移除自定义BusService,依赖MassTransit内置托管服务
你手动注册了BusService作为IHostedService,但MassTransit已自带托管服务负责总线生命周期管理。自定义实现若存在提前释放服务提供者或总线的逻辑,会导致消费时无法创建有效作用域。
修复:删除services.AddSingleton<IHostedService, BusService>();代码,让MassTransit自带托管服务接管总线启动/停止。
2. 调整重试与事务过滤器的顺序
当前重试过滤器在事务过滤器之前,重试时可能导致事务作用域与服务作用域生命周期不匹配,引发资源释放问题。
修复:将事务过滤器移至重试过滤器之前,确保每次重试都创建新的事务和作用域:
cfg.ReceiveEndpoint(queueConfig.CaseServiceBus, endPoint => { endPoint.UseTransaction(x => { x.Timeout = TimeSpan.FromSeconds(90); x.IsolationLevel = IsolationLevel.ReadCommitted; }); endPoint.UseMessageRetry(retry => { retry.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromMinutes(t)).ToArray()); }); endPoint.ConfigureSagas(context); endPoint.ConfigureConsumers(context); });
3. 验证Saga仓储与依赖服务的生命周期
服务器环境并发或资源回收策略更严格,若仓储或数据库连接生命周期配置错误,会提前释放资源。
修复建议:
- 数据库连接注册为
Scoped,避免单例实例被提前回收 - 仓储类注册为
Scoped或Transient,与消费作用域保持一致 - 若需要,显式指定Saga仓储生命周期:
x.AddSagaStateMachine<CaseSagaStateMachine, CaseSagaState>() .DapperRepository(sagaConnectionString) .AddScoped() // 按需调整为Singleton/Transient .Endpoint(e => { e.Name = queueConfig.CaseServiceBus; });
内容的提问来源于stack exchange,提问作者romandemidov
相关产品推荐
相关产品推荐

