【问题标题】:Implementing Publish Only Bus in MassTransit v3 with C# and RabbitMQ使用 C# 和 RabbitMQ 在 MassTransit v3 中实现仅发布总线
【发布时间】:2017-02-07 22:56:22
【问题描述】:

我正在尝试使用 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,但它非常基本,所以我想知道是否有人有任何建议?

【问题讨论】:

  • 虽然您不需要发布者/发送者的接收端点,但您确实需要它们,否则没有队列绑定到消息交换,并且消息不会路由到任何地方 - 因此消失了.

标签: c# rabbitmq masstransit


【解决方案1】:

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

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

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

【讨论】:

  • 首先设置 RabbitMQ 是否简单?我处于类似的情况,我需要保证接收者队列在应用程序开始发送消息时立即接收消息,而不管当时服务是否启动并运行,只要它们被保存并最终会得到处理.如果运行该服务一次可以满足此要求,那很好。这是文档可以使用一些示例的区域。假设这可行,我很乐意将其写下来。
  • GitHub 中有一个问题,本质上是在 RabbitMQ 中创建拓扑而不启动。自行连接方法带来的问题是类型系统中的细微差别可能无法正确手动设置,这可能会导致启动时出错。但是,如果您要发送到特定队列,则有一个查询字符串参数供发送方将交换绑定到队列。它要么是 bind 要么是 bindQueue = true。
  • 谢谢。你能提供问题链接吗?今天早上我终于可以把事情搞定了。一旦我与消费者一起启动一次,我就能够将其删除并在后续运行时仍然保留消息。我处于开发/探索模式,显然不是生产计划 :) 你确实提出了一些关于我一直在考虑的类型和版本控制消息的问题,但在我玩得更多之后,这是另一篇文章的主题跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多