Предотвратить добавление имени машины к имени конечной точки

У нас есть достаточное количество сервисов, которые мы уже разработали с помощью NServiceBus, и мы как раз находимся в процессе перехода от использования транспорта MSMQ к использованию транспорта SQL Server.

Для услуг NSB Hosted это было относительно просто. Но у нас возникла проблема с настройкой некоторых наших веб-сайтов (веб-API asp.net).

Мы самостоятельно размещаем веб-сайты со следующей конфигурацией:

NServiceBus.Configure.Serialization.Xml();
var bus = NServiceBus.Configure.With(/* specific assemblies */)
            .CastleWindsorBuilder(container)
            .DefineEndpointName(
                ConfigurationManager.AppSettings["nsb:EndpointName"])
            .DefiningCommandsAs(t =>
                t.GetCustomAttributes(typeof(/* our marker */), false)
                     .GetLength(0) > 0)
            .DefiningEventsAs(t =>
                t.GetCustomAttributes(typeof(/* our marker */), false)
                     .GetLength(0) > 0)
            .SetEndpointSLA(new TimeSpan(0,10,0))
            .UseNHibernateTimeoutPersister()
            .UseNHibernateSubscriptionPersister()
            .UseTransport<SqlServer>() //<-- Changed here
            .UnicastBus()
            .LoadMessageHandlers()
            //.DoNotCreateQueues()  //We create queues manually.
            .CreateBus()
            ;

Единственные строки, которые я изменил, это строка UseTransport<> (у которой ранее было Msmq) и, временно, строка .DoNotCreateQueues(), потому что я хотел заставить ее создавать таблицы очереди (пока я работаю локально под IIS Express)

Проблема в том, что когда он создает таблицы очереди, он добавляет имя моей машины к имени «базовой» таблицы. т.е. таблицы, которые он создает (когда параметр приложения EndpointName равен Service.Name), имеют форму:

Service.Name.MYMACHINENAME
Service.Name.Retries
Service.Name.Timeouts
Service.Name.TimeoutsDispatcher

Принимая во внимание, что когда он создает очереди MSMQ, он создает:

Service.Name
Service.Name.Retries
Service.Name.Timeouts
Service.Name.TimeoutsDispatcher

И действительно, подписчики, которые уже были обновлены до транспорта SQL Server, ищут таблицу очереди Service.Name для регистрации своих подписок.

Что я делаю неправильно или какая другая информация требуется для решения этой проблемы?


person Damien_The_Unbeliever    schedule 04.08.2014    source источник


Ответы (2)


Я разместил этот точный вопрос в группе Google Specific.net. Вот объяснение, которое я получил от Джона Саймонса:

Причина в том, что обратные вызовы NServiceBus коррелируются с использованием словаря в памяти, который отслеживает исходящие идентификаторы сообщений и входящие идентификаторы сообщений, то есть, другими словами, когда вы выполняете Bus.Send().Register(/* обратный вызов здесь */ ) на вашем веб-сайте мы добавляем элемент в этот словарь в памяти, говорящий, что мы отправили сообщение с идентификатором x, и мы также сохраняем делегат обратного вызова, а затем, когда мы получаем сообщения, мы проверяем этот словарь, и если идентификатор корреляционного сообщения совпадает, мы запустить делегат обратного вызова.

Таким образом, это означает, что если вы масштабируете свой веб-сайт (например, веб-ферму), где вы развертываете одну и ту же конечную точку на нескольких компьютерах, если имя первичной очереди для этих конечных точек было одинаковым, любая из этих масштабируемых конечных точек могла получать сообщения, которые предположим, что нужно перейти к определенной конечной точке/машине, что затем приведет к сбою, потому что сообщение обратного вызова не выйдет из словаря в памяти для этой конечной точки/машины.

Полная ветка здесь:

https://groups.google.com/d/msg/particularsoftware/W1RkPH6CBng/Ehiz0SPxKwoJ

person Phil Sandler    schedule 04.08.2014
comment
Спасибо. Это привело меня к обходному пути, который нам нужен здесь (мы не клиент, использующий обратные вызовы, мы издатель) - person Damien_The_Unbeliever; 04.08.2014

Ответ Фила привел меня к этому комментарий:

Это по дизайну. По умолчанию sql/rabbit/active будет включать имена компьютеров. Наш As_A_Server переопределяет это:

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

Причина в поддержке обратных вызовов по умолчанию

Что ж, в нашем случае мы не используем обратные вызовы — мы издатель, а не клиент, поэтому это было именно то исправление, которое нам требовалось.

person Damien_The_Unbeliever    schedule 04.08.2014