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

本文关键字:布总线 总线 实现 RabbitMQ v3 MassTransit 使用 | 更新日期: 2023-09-27 18:09:25

我正在尝试使用 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);
        }
    }

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

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

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

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

我遇到的问题是指定的 ReceiveEndpoint,消息将被使用并从发布者程序的队列中删除(这意味着使用者微服务不会处理排队的项目(。如果没有指定 RecieveEndpoint,将使用临时队列(使用者微服务不知道此临时队列的名称(,消息似乎永远不会排队,并且在总线停止时队列被删除,如果程序出现故障,那就不好了。

MassTransit 文档中有一个仅发送巴士的示例,但它非常基本,所以我想知道是否有人有任何建议?

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

接收终结点应位于服务中,与仅发布应用程序分开。这样,服务将具有接收终结点,并在应用程序发布消息时使用消息。

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

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