MassTransit故障处理配置

时间:2018-07-13 12:04:20

标签: .net-core rabbitmq masstransit

我在应用程序中配置故障使用者时遇到问题。问题在于,已消耗的消息将传递到* _error_skipped队列,并且不会完全消失。下面是一个非常简单的示例。客户端应用收到失败的消息,并从test_error队列中消失,但仍然存在于test_error_skipped队列中。

服务项目

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using GreenPipes;
using MassTransit;
using MassTransit.Util;

namespace MassTransitTest.Service
{

    public class RequestModel
    {
        public DateTime RequestTime { get; set; }
    }

    class MassTransitService:IDisposable
    {
        private readonly IBusControl _busControl;
        public MassTransitService()
        {
            _busControl = Bus.Factory.CreateUsingRabbitMq(configure =>
            {
                var host = configure.Host(new Uri("rabbitmq://localhost/mt_test"), h =>
                {
                    h.Username("guest");
                    h.Password("guest");
                });
                configure.ReceiveEndpoint(host, "test", c =>
                {
                    c.UseRetry(r => r.None());
                    c.Consumer<RequestConsumer>();
                });
            });
            TaskUtil.Await(_busControl.StartAsync());
            Console.WriteLine("bus started");
        }

        public void Dispose()
        {
            _busControl?.StopAsync().Wait();
        }
    }

    class RequestConsumer : IConsumer<RequestModel>
    {
        public Task Consume(ConsumeContext<RequestModel> context)
        {
            Console.WriteLine($"request with message id {context.MessageId} received: {context.Message.RequestTime}");
            throw new NotImplementedException();
        }
    }
}

客户项目

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using GreenPipes;
using MassTransit;
using MassTransit.Util;
using MassTransitTest.Service;

namespace MassTransitTest.Client
{
    class MassTransitClient
    {
        private readonly IBusControl _busControl;

        public MassTransitClient()
        {
            _busControl = Bus.Factory.CreateUsingRabbitMq(configure =>
            {
                var host = configure.Host(new Uri("rabbitmq://localhost/mt_test"), h =>
                {
                    h.Username("guest");
                    h.Password("guest");
                });enter code here
                configure.ReceiveEndpoint(host, "test_error", c =>
                {
                    c.Consumer<ErrorConsumer>();
                });
            });
            TaskUtil.Await(_busControl.StartAsync());
            Console.WriteLine("bus started");
        }

        public async Task Send()
        {
            Console.WriteLine("sending request");

            await (await _busControl.GetSendEndpoint(new Uri("rabbitmq://localhost/mt_test/test"))).Send(new RequestModel()
            {
                RequestTime = DateTime.Now
            });
            Console.WriteLine("request sent");

        }
    }
    class ErrorConsumer : IConsumer<Fault<RequestModel>>
    {
        public Task Consume(ConsumeContext<Fault<RequestModel>> context)
        {
            Console.WriteLine($"request with message id {context.Message.FaultedMessageId} failed. requested time: {context.Message.Message.RequestTime}");
            return Task.CompletedTask;
        }
    }
}

我正在使用.net core 2.1.1和MassTransit 5.1.3

1 个答案:

答案 0 :(得分:2)

首先要回答您的问题,该问题分为几个部分:

MassTransit接收端点在使用者引发异常时将消息移至_error队列。不建议在_error队列上创建接收端点,并且不应这样做。

如果您只想观察使用者是否发生故障,则可以创建一个单独的接收端点(例如 fault-queue )并注册您的Fault<T>使用者。 MassTransit将发布一条实现Fault<T>的消息,代理将通过接收端点将该消息路由到您的消费者。

但是,根据上述示例,您正在发送请求,并希望客户端知道是否发生了故障。为此,我建议使用请求客户端-它设置消息头,以将错误返回给请求发起者。它还允许发送响应。如果您不想等待响应,或者不想查看是否发生了故障,则上述故障观察器是您的最佳选择。

您可以在此处查看如何使用请求客户端: http://masstransit-project.com/MassTransit/usage/request-response.html

还有一个更灵活的请求客户端的新语法,您可以通过单元测试看到它: https://github.com/MassTransit/MassTransit/blob/develop/src/MassTransit.Futures.Tests/Request_Specs.cs#L42