2014-10-01 3 views
1

Я пишу «многорабочее» приложение с использованием верхней полки и ребуса.Несколько входных очередей в одном процессе ресуса

Моя идея состоит в использовании MyWorker1Namespace - MyWorker1Namespace.Messages, MyWorker2Namespace - MyWorker2Namespace.Messages Узор.

Я хотел был бы запустить приложение, не охватывая несколько процессов, вместо этого я хотел бы настроить приложение с очередями ввода moultiple, чтобы быть готовым разделить его на несколько процессов, если это необходимо.

Есть ли способ объявить несколько входных очередей и несколько рабочих потоков в одном приложении с помощью Rebus?

Я думаю, конфигурация должна быть что-то вроде этого:

<rebus inputQueue="MyWorker1Namespace.input" errorQueue="MyWorker1Namespace.error" workers="1" maxRetries="5"> </rebus> 
<rebus inputQueue="MyWorker2Namespace.input" errorQueue="MyWorker2Namespace.error" workers="1" maxRetries="5"> </rebus> 
... 

ответ

7

Поскольку Ребус app.config XML является своего рода оптимизировано для сценариев один-шины экземпляра в процессе, вы не можете настроить несколько шин полностью в XML, но нет ничего, что помешает вам запускать несколько экземпляров шины внутри одного и того же процесса.

Я часто делал это, например. в роли рабочих Azure, где я хочу размещать несколько логических конечных точек, не прибегая к затратам на физически отдельные развертывания, а также иногда делал это с помощью служб Windows, обслуживаемых Topshelf.

Обычно моя app.config заканчивается следующим XML:

<rebus workers="1"> 
    <add messages="SomeAssembly.Messages" endpoint="someEndpoint.input"/> 
    <add messages="AnotherAssembly.Messages" endpoint="anotherEndpoint.input"/> 
</rebus> 

, таким образом, позволяя мне настроить по умолчанию количество рабочих на шине и конечных точек отображений раз и навсегда. Затем, когда мое приложение запустится, он будет хранить контейнер IoC на шину в течение всего срока службы приложения - с Windsor я обычно получаю общий установщик шины, у которого есть параметры для имен очередей, что позволяет мне настраивать Windsor как это:

var containers = new List<IWindsorContainer> { 
    new WindsorContainer() 
     // always handlers first 
     .Install(FromAssembly.Containing<SomeEndpoint.SomeHandler>()) 

     // and then the bus, which gets started at this point 
     .Install(new RebusInstaller("someEndpoint.input", "error")) 

     // and then e.g. background timers and other "living things" 
     .Install(new PeriodicTimersInstannce()), 

    new WindsorContainer() 
     .Install(FromAssembly.Containing<AnotherEndpoint.AnotherHandler>()) 
     .Install(new RebusInstaller("anotherEndpoint.input", "error")) 
}; 

// and then remember to dispose each container when shutting down the process 

где RebusInstaller (что механизм Windsor), в основном просто ставит автобус с именами очередей в контейнер, например, вот так:

Configure.With(new WindsorContainerAdapter(container)) 
    .Transport(t => t.UseMsmq(_inputQueueName, _errorQueueName)) 
    .(...) etc 
    .CreateBus().Start(); 

Мне нравится идея, что каждый экземпляр контейнера IoC функционирует как самостоятельное логически самостоятельное приложение. Таким образом, было бы легко разбить вещи в будущем, если вы хотите, например, иметь возможность развертывать конечные точки независимо.

Надеюсь, это даст вам немного вдохновения :), пожалуйста, не стесняйтесь спрашивать, нужны ли вам больше указателей.

+0

Спасибо за интересный ответ. Обычно я использую Ninject как IoC. Я попытаюсь использовать аналогичный подход, используя единый контейнер с контекстным связыванием, чтобы вставлять выделенную шину для каждого рабочего. – Ganto

Смежные вопросы