Как правильно использовать диспетчер тайм-аута с дистрибьютором в NServiceBus 3+?

В версии до 3 было рекомендовано запускать диспетчер тайм-аута как отдельный процесс в кластере, помимо дистрибьютора. (Подробно здесь: http://support.nservicebus.com/customer/portal/articles/965131-deploying-nservicebus-in-a-windows-failover-cluster).

После включения диспетчера тайм-аута в качестве вспомогательной сборки, как правильно использовать его при горизонтальном масштабировании с помощью дистрибьютора?

Должен ли каждый работник службы A работать с включенным диспетчером тайм-аута или только процесс распространителя для службы A должен быть настроен для запуска диспетчера тайм-аута для службы A?

Если каждый рабочий запускает его, используют ли они один и тот же экземпляр Raven для хранения таймаутов? (И если да, то как сделать так, чтобы два или более рабочих не использовали один и тот же истекший тайм-аут одновременно?)


person janovesk    schedule 05.02.2013    source источник


Ответы (2)


Позвольте мне сам четко ответить на этот вопрос.

После долгих поисков и помощи Андреаса Олунда из команды NSB (http://tech.groups.yahoo.com/group/nservicebus/message/17758) правильный ответ на этот вопрос:

  • Как упоминал Уди Дахан, по замыслу ТОЛЬКО дистрибьютор / главный узел должен запускать диспетчер тайм-аута в сценарии горизонтального масштабирования.
  • К сожалению, в ранних версиях NServiceBus 3 это реализовано не так, как задумано.

У вас есть 3 проблемы:

1) Работа с профилем распространителя НЕ запускает диспетчер тайм-аута.

Обходной путь:

Запустите диспетчер тайм-аута на дистрибьюторе самостоятельно, включив в него этот код:

class DistributorProfileHandler : IHandleProfile<Distributor> 
{
   public void ProfileActivated()
   {
       Configure.Instance.RunTimeoutManager();
   }
}

Если вы запускаете главный профиль, это не проблема, поскольку на главном узле автоматически запускается диспетчер тайм-аута.

2) Каждый рабочий, работающий с профилем рабочего, запускает локальный диспетчер тайм-аута.

Это не так, как задумано, и мешает опросу хранилища тайм-аутов и отправке тайм-аутов. Все рабочие опрашивают хранилище тайм-аутов, говоря: «Дайте мне ближайшие таймауты для MASTERNODE». Обратите внимание, что они запрашивают таймауты для MASTERNODE, а не для W1, W2 и т. Д. Таким образом, несколько воркеров могут в конечном итоге получить одни и те же тайм-ауты из хранилища тайм-аутов одновременно, что приведет к конфликтам с Raven при удалении тайм-аутов из него.

Диспетчеризация всегда происходит через ЛОКАЛЬНЫЕ очереди .timouts / .timeoutsdispatcher, в то время как ДОЛЖНА осуществляться через очереди диспетчера тайм-аута на MasterNode / Distributor.

Обходной путь, вам нужно сделать оба:

а) Отключите диспетчер тайм-аута для рабочих. Включите этот код в своих рабочих

class WorkerProfileHandler:IHandleProfile<Worker>
{
    public void ProfileActivated()
    {
        Configure.Instance.DisableTimeoutManager();
    }
}

б) Перенаправьте NServiceBus на рабочих, чтобы использовать очередь .timeout на главном узле / распространителе.

Если вы этого не сделаете, любой вызов RequestTimeout или Defer для рабочего прекратит работу, за исключением того, что вы забыли настроить диспетчер тайм-аута. Включите это в конфигурацию вашего рабочего:

<UnicastBusConfig TimeoutManagerAddress="{endpointname}.Timeouts@{masternode}" /> 

3) Ошибочные сообщения «Готово» обратно дистрибьютору.

Поскольку диспетчер тайм-аута отправляет сообщения непосредственно в очереди ввода рабочих, не удаляя запись из доступных воркеров в очереди хранилища распределителя, рабочие отправляют ошибочные сообщения «Готово» обратно распределителю после обработки тайм-аута. Это происходит, даже если вы исправили 1 и 2, и не имеет значения, был ли тайм-аут получен от локального диспетчера тайм-аута на рабочем или на распределителе / ​​главном узле. Следствием этого является создание дополнительной записи в очереди хранилища на распределителе для каждого тайм-аута, обрабатываемого работником.

Решение: используйте NServiceBus 3.3.15 или новее.

person janovesk    schedule 10.02.2013
comment
+1 спасибо, что поделились этим потрясающим и подробным ответом. это услуга обществу. - person Dave Rael; 14.02.2013
comment
Спасибо за это. Мы реализовали эти обходные пути, но все еще видим дополнительные «готовые» сообщения в очереди хранилища. Я считаю, что это из-за вашего №3. К сожалению, несколько дней назад Андреас закрыл номер 954. - person cfbarbero; 02.04.2013
comment
Привет, Yobi21! Накапливаются ли дополнительные готовые сообщения со временем или вы просто получаете пару дополнительных при запуске? Если это позже, я сообщил о состоянии гонки между запущенным рабочим и рабочим, готовым к новым сообщениям, которые могут возникнуть при запуске конечной точки, особенно если конечная точка подписывается на любое из своих собственных событий. Ничего страшного, но последнее, что я слышал, планируется исправить в версии 4.1. Проверьте: github.com/NServiceBus/NServiceBus/issues/978 - person janovesk; 02.04.2013
comment
Задокументировал проблему в этой теме ссылка - person cfbarbero; 15.04.2013

В версии 3+ мы создали концепцию главного узла, в котором размещены все спутники, такие как распределитель, диспетчер тайм-аута, шлюз и т. Д.

Главный узел очень просто запустить - вы просто передаете флаг / master процессу NServiceBus.Host.exe, и он запускает все за вас. Итак, с точки зрения развертывания, где вы раньше развертывали дистрибьютора, теперь вы развертываете главный узел.

person Udi Dahan    schedule 06.02.2013
comment
Хорошо, достаточно честно. Так что нет диспетчера тайм-аута для каждого рабочего. Но главный профиль также заставляет процесс вести себя как воркер, он участвует в качестве получателя и обработчика сообщений в балансировке нагрузки, как и другие воркеры. Я хотел бы сохранить эту работу кластеризованных узлов, чтобы максимизировать ресурсы, доступные для фактического распределения другим рабочим. Есть ли поддерживаемый способ сделать это при использовании профиля дистрибьютора у дистрибьютора, а не главного профиля? Или каким-то образом убедиться, что главный узел не ведет себя как рабочий? - person janovesk; 06.02.2013
comment
См. Раздел профилей, связанных с функциями на этой странице: support.nservicebus. ru / customer / portal / article / - person Udi Dahan; 06.02.2013
comment
У меня есть и я ничего не вижу о том, должны ли рабочие запускать диспетчер тайм-аута или нет? - person janovesk; 06.02.2013
comment
@UdiDahan Я бы хотел, чтобы вы подробно остановились на своем ответе, поскольку документация, на которую вы ссылаетесь, не отвечает на вопрос janovesk в хорошем смысле. - person Marius; 06.02.2013
comment
Я проверил, и мы запускаем управление тайм-аутом по умолчанию на каждом узле (главном и рабочем). Мы изменим это в версии 4.0 и сделаем так, чтобы он работал только на главном узле. - person Udi Dahan; 07.02.2013