【问题标题】:How to override MassTransit default exchange and queue topology convention?如何覆盖 MassTransit 默认交换和队列拓扑约定?
【发布时间】:2019-05-10 09:30:09
【问题描述】:

正如 [在我关于 SO 的一个问题中] (Why a simple configuration in MassTransit creates 2 queues and 3 exchanges?) 所指出的,MassTransit for RabbitMQ 自动创建一定数量的队列并针对给定的简单配置进行交换:

交换,所有扇出:

  • ConsoleApp1:Program-YourMessage: 耐用
  • VP0003748_dotnet_bus_6n9oyyfzxhyx9ybobdmpj8qeyt:自动删除和持久化?
  • test_queue: 耐用

队列:

  • VP0003748_dotnet_bus_6n9oyyfzxhyx9ybobdmpj8qeyt: x-expire 60000
  • test_queue:耐用

但是,我发现无法覆盖这些交换和队列的命名有点令人沮丧。有什么办法可以改变吗?

例如,如果您重构某些类型或命名空间,您最终可能会用大量不再使用的交换器污染您的 RabbitMQ 实例 =/

我了解test_queue,因为这是我决定如此公平的事情。 类型很容易受到更改/重构。

【问题讨论】:

标签: c# .net-core rabbitmq masstransit


【解决方案1】:

这是一种简单有效的方法:https://bartwullems.blogspot.com/2018/09/masstransitchange-exchange-naming.html

但最好在此处删除一些 dotnet 核心代码,以帮助任何刚开始的人。

我们基于配置的自定义格式化程序:

public class BusEnvironmentNameFormatter : IEntityNameFormatter
{
    private readonly IEntityNameFormatter _original;
    private readonly string _prefix;

    public BusEnvironmentNameFormatter(IEntityNameFormatter original, SomeAppSettingsSection busSettings)
    {
        _original = original;
        _prefix = string.IsNullOrWhiteSpace(busSettings.Environment)
            ? string.Empty // no prefix
            : $"{busSettings.Environment}:"; // custom prefix
    }

    // Used to rename the exchanges
    public string FormatEntityName<T>()
    {
        var original = _original.FormatEntityName<T>();
        return Format(original);
    }

    // Use this one to rename the queue
    public string Format(string original)
    {
        return string.IsNullOrWhiteSpace(_prefix)
            ? original
            : $"{_prefix}{original}";
    }
}

然后要使用它,我们会这样做:

var busSettings = busConfigSection.Get<SomeAppSettingsSection>();
var rabbitMqSettings = rabbitMqConfigSection.Get<SomeOtherAppSettingsSection>();

services.AddMassTransit(scConfig =>
{
    scConfig.AddConsumers(consumerAssemblies);

    scConfig.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(rmqConfig =>
    {
        rmqConfig.UseExtensionsLogging(provider.GetRequiredService<ILoggerFactory>());

        // Force serialization of default values: null, false, etc
        rmqConfig.ConfigureJsonSerializer(jsonSettings =>
        {
            jsonSettings.DefaultValueHandling = DefaultValueHandling.Include;
            return jsonSettings;
        });

        var nameFormatter = new BusEnvironmentNameFormatter(rmqConfig.MessageTopology.EntityNameFormatter, busSettings);
        var host = rmqConfig.Host(new Uri(rabbitMqSettings.ConnectionString), hostConfig =>
        {
            hostConfig.Username(rabbitMqSettings.Username);
            hostConfig.Password(rabbitMqSettings.Password);
        });

        // Endpoint with custom naming
        rmqConfig.ReceiveEndpoint(host, nameFormatter.Format(busSettings.Endpoint), epConfig =>
        {
            epConfig.PrefetchCount = busSettings.MessagePrefetchCount;
            epConfig.UseMessageRetry(x => x.Interval(busSettings.MessageRetryCount, busSettings.MessageRetryInterval));
            epConfig.UseInMemoryOutbox();

            //TODO: Bind messages to this queue/endpoint
            epConfig.MapMessagesToConsumers(provider, busSettings);
        });

        // Custom naming for exchanges
        rmqConfig.MessageTopology.SetEntityNameFormatter(nameFormatter);
    }));
});

【讨论】:

    【解决方案2】:

    可以使用 IRabbitMqBusFactoryConfigurator 的 OverrideDefaultBusEndpointQueueName 方法更改队列的名称,方法如下

    var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
    {
        sbc.Host("rabbitmq://localhost/");
    
        sbc.OverrideDefaultBusEndpointQueueName("endpoint");
    });
    

    【讨论】:

      猜你喜欢
      • 2021-11-03
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      相关资源
      最近更新 更多