NServiceBus事件订阅不使用Azure Service Bus

时间:2014-06-04 02:01:34

标签: 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 Service Bus队列:

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

我已将网络角色设置为扩展为两个实例,并且正如预期的那样,会创建两个队列(电子商务和电子商务-1)。但是,我没有看到在videostore.sales.events主题下创建的其他主题订阅。相反,我看到了:

Missing Subscriptions

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

我在这里缺少什么?我在电子商务实例的一个上获得了这个活动,但两者都没有。即使这不是扩展SignalR的正确方法,我的用例也扩展到缓存失效之类的东西。

我也觉得很奇怪,正在创建两个错误和审计队列。为什么会这样?

更新

Yves是对的。 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类。相反,我必须在启动总线之前手动调用它。来自我的Global.asax.cs:

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

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

Correct Subscriptions

不确定为什么它会忽略我的IConfigureThisEndpoint,但这样可行。

1 个答案:

答案 0 :(得分:3)

这听起来像个bug,你能在https://github.com/Particular/NServiceBus.Azure

上提出一个github问题

尽管如此,我认为使用信号器的横向扩展功能而不是使用QueuePerInstance更好,因为信号器需要在内部以及在横向扩展模式下运行时复制其他信息(如连接/组映射)。

更新

我认为我看到了这个问题,订阅也应该个性化,在当前的命名惯例中并非如此

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

虽然它在queuenamingconventions

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

由于这些约定是公开的,您可以通过更改IWantCustomInitialization中的func来覆盖它们以解决问题,直到我可以获得修复,只需复制当前方法并添加个性化逻辑。队列个性化器虽然是内部的,但您必须从

复制该类

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