azure - NServiceBus 事件订阅不适用于 Azure 服务总线

标签 azure nservicebus servicebus azureservicebus

我正在尝试修改 Azure-based Video Store sample app以便前端电子商务网站可以横向扩展。

具体来说,我希望网站的所有实例都能收到有关 OrderPlaced 等事件的通知,这样无论客户端 Web 应用程序恰好通过 SignalR 连接到哪个 Web 服务器,它都会正确接收通知并更新 UI。

下面是我当前在 Global.asax 中的配置:

        Feature.Disable<TimeoutManager>();

        Configure.ScaleOut(s => s.UseUniqueBrokerQueuePerMachine());

        startableBus = Configure.With()
            .DefaultBuilder()
            .TraceLogger()
            .UseTransport<AzureServiceBus>()
            .PurgeOnStartup(true)
            .UnicastBus()
            .RunHandlersUnderIncomingPrincipal(false)
            .RijndaelEncryptionService()
            .CreateBus();

        Configure.Instance.ForInstallationOn<Windows>().Install();

        bus = startableBus.Start();

我还使用以下方法配置了 Azure 服务总线队列:

class AzureServiceBusConfiguration : IProvideConfiguration<NServiceBus.Config.AzureServiceBusQueueConfig>
{
    public AzureServiceBusQueueConfig GetConfiguration()
    {
        return new AzureServiceBusQueueConfig()
        {
            QueuePerInstance = true     
        };
    }
}

我已将 Web 角色设置为扩展到两个实例,并且按预期创建了两个队列(ecommerce 和 ecommerce-1)。但是,我没有看到在 videostore.sales.events 主题下创建其他主题订阅。相反,我看到:

Missing Subscriptions

我认为您会在 Videostore.Sales.Events 主题下看到 VideoStore.ECommerce-1.OrderCancelled 和 VideoStore.ECommerce-1.OrderPlaced 订阅。或者这不是使用 Azure 服务总线时存储订阅的方式?

我在这里缺少什么?我在其中一个电子商务实例上收到该事件,但从未在两个电子商务实例上收到该事件。即使这不是扩展 SignalR 的正确方法,我的用例也扩展到了缓存失效等内容。

我还发现创建两个错误和审核队列很奇怪。为什么会发生这种情况?

更新

伊夫是正确的。 AzureServiceBusSubscriptionNamingConvention 未应用正确的个性化名称。我能够通过实现以下 EndpointConfig 来解决此问题:

namespace VideoStore.ECommerce
{
    public class EndpointConfig : IConfigureThisEndpoint, IWantCustomInitialization
    {
        public void Init()
        {
            AzureServiceBusSubscriptionNamingConvention.Apply = BuildSubscriptionName;
            AzureServiceBusSubscriptionNamingConvention.ApplyFullNameConvention = BuildSubscriptionName;
        }

        private static string BuildSubscriptionName(Type eventType)
        {
            var subscriptionName = eventType != null ? Configure.EndpointName + "." + eventType.Name : Configure.EndpointName;

            if (subscriptionName.Length >= 50)
                subscriptionName = new DeterministicGuidBuilder().Build(subscriptionName).ToString();

            if (!SettingsHolder.GetOrDefault<bool>("ScaleOut.UseSingleBrokerQueue"))
                subscriptionName = Individualize(subscriptionName);

            return subscriptionName;
        }

        public static string Individualize(string queueName)
        {
            var parser = new ConnectionStringParser();
            var individualQueueName = queueName;
            if (SafeRoleEnvironment.IsAvailable)
            {
                var index = parser.ParseIndexFrom(SafeRoleEnvironment.CurrentRoleInstanceId);

                var currentQueue = parser.ParseQueueNameFrom(queueName);
                if (!currentQueue.EndsWith("-" + index.ToString(CultureInfo.InvariantCulture))) //individualize can be applied multiple times
                {
                    individualQueueName = currentQueue
                                              + (index > 0 ? "-" : "")
                                              + (index > 0 ? index.ToString(CultureInfo.InvariantCulture) : "");
                }
                if (queueName.Contains("@"))
                    individualQueueName += "@" + parser.ParseNamespaceFrom(queueName);
            }

            return individualQueueName;
        }
    }
}

但是,我无法让 NServiceBus 识别我的 EndpointConfig 类。相反,我必须在启动公共(public)汽车之前手动调用它。来 self 的 Global.asax.cs:

new EndpointConfig().Init();
bus = startableBus.Start();

完成此操作后,订阅名称将按预期显示:

Correct Subscriptions

不确定为什么它忽略我的 IConfigureThisEndpoint,但这有效。

最佳答案

这听起来像是一个错误,您可以在 https://github.com/Particular/NServiceBus.Azure 上提出有关此问题的 github 问题吗?

也就是说,我认为最好使用 signalr 的横向扩展功能,而不是使用 QueuePerInstance,因为在横向扩展模式下运行时,signalr 还需要在内部复制其他信息,例如(连接/组映射)。

更新:

我想我看到了这个问题,订阅也应该是个性化的,这在当前的命名约定中不是这样的

https://github.com/Particular/NServiceBus.Azure/blob/master/src/NServiceBus.Azure.Transports.WindowsAzureServiceBus/NamingConventions/AzureServiceBusSubscriptionNamingConvention.cs

当它在队列命名约定中时

https://github.com/Particular/NServiceBus.Azure/blob/master/src/NServiceBus.Azure.Transports.WindowsAzureServiceBus/NamingConventions/AzureServiceBusQueueNamingConvention.cs#L27

由于这些约定是公共(public)的,您可以通过更改 IWantCustomInitialization 中的函数来覆盖它们来解决问题,直到我可以修复,只需复制当前方法并添加个性化器逻辑即可。不过,队列个性化器是内部的,因此您必须从

复制该类

https://github.com/Particular/NServiceBus.Azure/blob/master/src/NServiceBus.Azure.Transports.WindowsAzureServiceBus/Config/QueueIndividualizer.cs

关于azure - NServiceBus 事件订阅不适用于 Azure 服务总线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24027847/

相关文章:

azure - 当前帐户中没有订阅 azure - Rider

c# - 我在哪里可以获得 'IgnoreDatabaseOutOfSync' 属性

Azure 我删除了门户上的 VMAccessForLinux 扩展

c# - 如何在 .Net 5 中将 Azure 函数过滤与 FunctionInitationFilterAttribute 结合使用

queue - NServiceBus 单进程,但多个输入队列

mule - Windows Server 服务总线对比 NServicebus 对比 Mule ESB

json.net - 从 RavenDB 获取 NServiceBus 订阅

c# - 我如何使用 NServiceBus 做竞争消费者

.net - 如何在网关模式下使用NServiceBus

.net - 在没有事件存储的情况下在服务总线上重播事件