Masstransit框架中实现消息的动态监听
在使用消息队列中,会有这么一个场景:要求发送的queue是按照元数据配置自动生成,监听队列的逻辑也要对应的自动生成。这种
动态监听队列的场景可以使用Masstransit框架解决。
1.Producer
消息的生成者搭建一个webapi项目,指定virtual host,可以自动配置queue的名称
public void ConfigureServices(IServiceCollection services)
{
services.AddMassTransit(x => {
x.UsingRabbitMq((context, config) =>
{
config.Host("rabbitmq://localhost:5672", host =>
{
host.Username("root");
host.Password("root");
});
});
});
services.AddControllers();
}
然后写一个api程序
[ApiController]
[Route("[controller]")]
public class PublishController : ControllerBase
{
private readonly IPublishEndpoint _publishEndpoint;
public PublishController(IPublishEndpoint publishEndpoint)
{
_publishEndpoint = publishEndpoint;
}
[HttpGet]
public async Task<string> Get(string name)
{
await _publishEndpoint.Publish(new OrderEto
{
Id = Guid.NewGuid(),
Name = name,
CreationTime = DateTime.Now
});
return "success";
}
}
注意:OrderEto这个实体是共享同一个命名空间与名称的类
2.Consumer
消费者则使用通用主机项目
public static async Task Main(string[] args) { await Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddMassTransit(x => { x.AddConsumer<OrderEtoConsumer>(typeof(OrderEtoConsumerDefinition)); x.UsingRabbitMq((context, config) => { config.Host("rabbitmq://localhost:5672", hostconfig => { hostconfig.Username("root"); hostconfig.Password("root"); }); config.ConfigureEndpoints(context); }); }); }) .Build() .RunAsync(); }
然后写一个consumer的类,这个类就是去消费的具体逻辑
public class OrderEtoConsumer : IConsumer<OrderEto>
{
public Task Consume(ConsumeContext<OrderEto> context)
{
Console.WriteLine($"MassTransit.Consumer.One 收到消息:{JsonSerializer.Serialize(context.Message)}");
return Task.CompletedTask;
}
}
public class OrderEtoConsumerDefinition : ConsumerDefinition<OrderEtoConsumer>
{
protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator, IConsumerConfigurator<OrderEtoConsumer> consumerConfigurator)
{
endpointConfigurator.UseMessageRetry(r => r.Intervals(500, 1000));
}
}
将两个站点同时启动,进行测试:

所以结论:
消费者的Model确定后,就相当于某类消息固定了,在不特指queue的情况下,可以监听所有queue的信息,如果在代码指定了具体的queue的名称则实现不了。
因为此时需要定义消息体跟consumer处理类。

浙公网安备 33010602011771号