使用C#和RabbitMQ在MassTransit v3中实现仅发布总线

Ric*_*use 6 c# masstransit rabbitmq

我正在尝试使用C#和RabbitMQ在MassTransit v3中实现仅发布总线,其中总线没有消费者.概念是消息将被发布和排队,然后单独的微服务将消耗来自队列的消息.查看此SO答案,必须指定接收端点,以便实际排队邮件.然而,这似乎与MassTransit文档中常见的问题相矛盾,后者表示If you need to only send or publish messages, don’t create any receive endpoints.

以下是一些示例代码:

    public class Program
    {
        static void Main(string[] args)
        {
            var bus = BusConfigurator.ConfigureBus();

            bus.Start();

            bus.Publish<IItemToQueue>(new ItemToQueue { Text = "Hello World" }).Wait();

            Console.ReadKey();

            bus.Stop();
        }
    }

    public static class BusConfigurator
    {
        public static IBusControl ConfigureBus()
        {
            var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                var host = cfg.Host(new Uri("rabbitmq://localhost/"), hst =>
                {
                    hst.Username("guest");
                    hst.Password("guest");
                });

                cfg.ReceiveEndpoint(host, "queuename", e =>
                {
                    e.Consumer<MyConsumer>();
                });
            });

            return bus;
        }
    }

    public interface IItemToQueue
    {
        string Text { get; set; }
    }

    public class ItemToQueue : IItemToQueue
    {
        public string Text { get; set; }
    }

    public class MyConsumer : IConsumer<IItemToQueue>
    {
        public async Task Consume(ConsumeContext<IItemToQueue> context)
        {
            await Console.Out.WriteLineAsync(context.Message.Text);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在此示例中,收到按预期在RabbitMQ的队列中的消息,并且这是通过消耗MyConsumer其中写入的Hello World到控制台和该消息然后从队列中删除.

但是,当我从上面删除以下代码并重新运行示例时:

cfg.ReceiveEndpoint(host, RabbitMqConstants.ValidationQueue, e =>
{
    e.Consumer<MyConsumer>();
}); 
Run Code Online (Sandbox Code Playgroud)

创建临时队列(使用生成的名称),并且似乎永远不会将消息放入临时队列中.然后在总线停止时删除此队列.

我的问题是,如果指定了ReceiveEndpoint,该消息将被消耗掉,并从发布程序队列(意味着消费者微服务不会处理排队的项目)中删除.如果没有指定RecieveEndpoint,则使用临时队列(并且消费者微服务器不会知道此临时队列的名称),该消息似乎永远不会排队,并且当总线停止时队列被删除,如果不是该计划失败了.

在MassTransit文档发送一个唯一的总线的例子,但它是非常基本的,所以我想知道如果任何人有什么建议?

Chr*_*son 2

接收端点应该位于您的服务中,与仅发布应用程序分开。这样,服务将拥有接收端点并在应用程序发布消息时使用它们。

如果应用程序中有接收端点,则应用程序将使用消息,因为它具有与接收端点中指定的相同队列名称。

您需要做的是创建另一个具有相同配置(包括接收端点)的服务 - 并将接收端点从您的应用程序中取出。此时,服务将具有接收端点并使用队列中的消息。即使服务停止,消息也会继续传递到队列,一旦服务启动,它们就会开始使用。