.Net Core之RabbitMQ

.Net Core之RabbitMQ

.Net Core下使用RabbitMQ很方便,不过这里还是采用了EasyNetQ这一二次封装的库

  • EasyNetQ对Rabbit原生接口进行了二次封装,提供了IBus作为入口,入门使用的话更加方便,要想使用,只需要在Startup的时候助于一个Singleton的IBus即可:

    service.AddSingleton(RabbitHutch.CreateBus(rabbitMqConnection));
    
  • EasyNetQ还提供了一个自动订阅的方法,可以方便一次性自动订阅-AutoSubscriber:

    public static class EasyNetQExtension
    {
        private static void InternalInitEasyNetQ(IServiceCollection service, string rabbitMqConnection)
        {
            service.AddSingleton(RabbitHutch.CreateBus(rabbitMqConnection));
            service.AddSingleton<IAutoSubscriberMessageDispatcher, ConsumerMessageDispatcher>(
                serviceProvider => new ConsumerMessageDispatcher(
                    serviceProvider, serviceProvider.GetRequiredService<ILogger<ConsumerMessageDispatcher>>()));
    
            var consumerTypes = Assembly.GetExecutingAssembly().GetTypes()
                                        .Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface)
                                        .Where(x => x.GetInterfaces().Any(t => t.Name == typeof(IConsume<>).Name));
            foreach (var consumerType in consumerTypes)
            {
                service.AddTransient(consumerType);
            }
    
            var consumerAsyncTypes = Assembly.GetExecutingAssembly().GetTypes()
                                             .Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface)
                                             .Where(x => x.GetInterfaces().Any(t => t.Name == typeof(IConsumeAsync<>).Name));
            foreach (var consumerAsyncType in consumerAsyncTypes)
            {
                service.AddTransient(consumerAsyncType);
            }
        }
    
        public static void AddEasyNetQ(this IServiceCollection service, string rabbitMqConnectionString)
        {
            InternalInitEasyNetQ(service, rabbitMqConnectionString);
        }
    
        public static void UseEasyNetQ(this IApplicationBuilder app)
        {
            var bus = app.ApplicationServices.GetRequiredService<IBus>();
            var autoSubscriber = new AutoSubscriber(bus, "Consumer")
            {
                //由于要配合EF Core使用,而EasyNetQ默认的IAutoSubscriberMessageDispatcher对依赖注入的DBContext支持的不太好,需要自定义Dispatcher
                AutoSubscriberMessageDispatcher = app.ApplicationServices.GetRequiredService<IAutoSubscriberMessageDispatcher>()
            };
            autoSubscriber.Subscribe(Assembly.GetExecutingAssembly());
            autoSubscriber.SubscribeAsync(Assembly.GetExecutingAssembly());
        }
    }
    
    public class ConsumerMessageDispatcher : IAutoSubscriberMessageDispatcher
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ILogger<ConsumerMessageDispatcher> _logger;
    
        public ConsumerMessageDispatcher(IServiceProvider serviceProvider, ILogger<ConsumerMessageDispatcher> logger)
        {
            _serviceProvider = serviceProvider;
            _logger = logger;
        }
    
        public void Dispatch<TMessage, TConsumer>(TMessage message) where TMessage : class where TConsumer : class, IConsume<TMessage>
        {
            try
            {
                TConsumer consumer = _serviceProvider.GetRequiredService<TConsumer>();
                consumer.Consume(message);
            }
            catch (Exception exception)
            {
                throw;
            }
        }
    
        public async Task DispatchAsync<TMessage, TConsumer>(TMessage message) where TMessage : class where TConsumer : class, IConsumeAsync<TMessage>
        {
            try
            {
                TConsumer consumer = _serviceProvider.GetRequiredService<TConsumer>();
                await consumer.ConsumeAsync(message);
            }
            catch (Exception exception)
            {
                throw;
            }
        }
    }
    
  • 异常追踪:

    • EasyNetQ会自动把异常跑到一个默认的错误队列:EasyNetQ_Default_Error_Queue,算是消息队列的Log,可以分析报错。

    • 同时可以开启Rabbit的Trace功能,就可以自动生成log文件,可以到management-admin-trace追踪记录,调试Bug:

      • 开启:rabbitmq rabbitmq-plugins enable rabbitmq_tracing

        ​ rabbitmq rabbitmqctl trace_on

      • 关闭:rabbitmq rabbitmq-plugins disable rabbitmq_tracing

        ​ rabbitmq rabbitmqctl trace_off

posted @ 2019-03-16 14:01  shadowxs  阅读(140)  评论(0)    收藏  举报