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

时间:2016-09-29 14:37:30

标签: c# rabbitmq masstransit

我正在尝试使用C#和RabbitMQ在MassTransit v3中实现仅发布总线,其中总线没有消费者。概念是消息将被发布和排队,然后单独的微服务将消耗来自队列的消息。查看this SO answer,必须指定接收端点,以便实际对消息进行排队。但是contradict the common gotchas in the MassTransit docs显示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);
        }
    }

在此示例中,我按预期在RabbitMQ队列中收到消息,这由MyConsumer使用,它将Hello World写入控制台,然后从队列中删除消息。

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

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

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

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

an example of a send only bus in the MassTransit docs,但它非常基本,所以我想知道是否有人有任何建议?

1 个答案:

答案 0 :(得分:2)

接收端点应该在您的服务中,与仅发布应用程序分开。这样,该服务将具有接收端点并消耗应用程序发布的消息。

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

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