问题
I am using MassTransit 7.1.4.0 together with RabbitMQ 3.8.7.
I have a consumer which simply throws an exception, and I have a fault consumer which Console.WriteLine
the fact that a fault occurred.
The fault consumer is not called. I also tried using a fault consumer definition. Also that does not work.
Below is the entire program.
using System;
using System.Threading.Tasks;
using GreenPipes;
using MassTransit;
using MassTransit.ConsumeConfigurators;
using MassTransit.Definition;
using Microsoft.Extensions.DependencyInjection;
namespace FaultConsumer
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello Fault Consumer!");
var services = new ServiceCollection();
services.AddMassTransit(x =>
{
x.AddConsumer<MyConsumer>(typeof(MyConsumerDefinition));
x.AddConsumer<MyFaultConsumer>();//typeof(MyFaultConsumerDefinition));
x.SetKebabCaseEndpointNameFormatter();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("rabbitmq://localhost");
cfg.ConfigureEndpoints(context);
});
});
var serviceProvider = services.BuildServiceProvider();
var bus = serviceProvider.GetRequiredService<IBusControl>();
await bus.StartAsync();
await bus.Publish(new SubmitOrder() { DateTimeStamp = DateTime.Now });
Console.WriteLine("Press any key to exit");
await Task.Run(() => Console.ReadKey());
await bus.StopAsync();
}
}
class SubmitOrder
{
public DateTime DateTimeStamp { get; set; }
}
class MyConsumer : IConsumer<SubmitOrder>
{
public async Task Consume(ConsumeContext<SubmitOrder> context)
{
Console.WriteLine($"Attempting to consume {context.GetRetryCount()} {context.GetRetryAttempt()}");
throw new Exception(context.GetRetryCount().ToString());
}
}
class MyConsumerDefinition : ConsumerDefinition<MyConsumer>
{
public MyConsumerDefinition()
{
EndpointName = "order-service-202102081221";
ConcurrentMessageLimit = 8;
}
protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<MyConsumer> consumerConfigurator)
{
//endpointConfigurator.UseMessageRetry(r => r.Intervals(100, 200, 500, 800, 1000));
endpointConfigurator.UseMessageRetry(r => r.Immediate(5));
endpointConfigurator.UseInMemoryOutbox();
}
}
class MyFaultConsumer : IConsumer<Fault<MyConsumer>>
{
public async Task Consume(ConsumeContext<Fault<MyConsumer>> context)
{
Console.WriteLine("Fault");
await Task.CompletedTask;
}
}
// class MyFaultConsumerDefinition : ConsumerDefinition<MyFaultConsumer>
// {
// public MyFaultConsumerDefinition()
// {
// // override the default endpoint name
// EndpointName = "order-service-faults-202102081221";
// // limit the number of messages consumed concurrently
// // this applies to the consumer only, not the endpoint
// ConcurrentMessageLimit = 8;
// }
// protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
// IConsumerConfigurator<MyFaultConsumer> consumerConfigurator)
// {
// // configure message retry with millisecond intervals
// endpointConfigurator.UseMessageRetry(r => r.Intervals(100, 200, 500, 800, 1000));
// // use the outbox to prevent duplicate events from being published
// endpointConfigurator.UseInMemoryOutbox();
// }
// }
}
回答1:
Faults are published based on message type, not consumer type.
Your fault consumer should be consuming Fault<SubmitOrder>
.
class MyFaultConsumer :
IConsumer<Fault<SubmitOrder>>
{
public Task Consume(ConsumeContext<Fault<SubmitOrder>> context)
{
Console.WriteLine("Fault");
return Task.CompletedTask;
}
}
来源:https://stackoverflow.com/questions/66101730/why-does-my-masstransit-fault-consumer-not-get-called