2013-10-25 3 views
2

Мой сценарий заключается в следующем:Действительно ли нужна очередь MSMQ среднего уровня?

У меня есть несколько веб-серверов, что:

  1. потребность общаться с бэкэнда (IBus.Publish/IBus.Subscribe)
  2. потребность в общении друг с-другом (IBus.Publish/IBus.Subscribe)

Помимо веб-серверов, у меня есть несколько служб Windows, которые потребляют одни и те же сообщения.

Для того, чтобы сделать эту работу, у меня есть веб-серверы, отправляющие сообщения в центральный концентратор, единственной способностью которого является обернуть сообщение в новом типе сообщения и опубликовать его всем подписчикам.

Могу ли я как-то избежать этого, чтобы я мог публиковать сообщения непосредственно из веб-серверов?

EDIT (добавлен некоторый код) - Текущая ситуация:

... WebServer 
_bus.Send(new Message{Body="SomethingChanged"}); 

... Hub 
public void Handle(Message message){ 
    _bus.Publish(new WrappedMessage{Message = message}) 
} 

... Handlers (WebServers, WindowsServices etc) 
public void Handle(WrappedMessage message){ 
    //Actually do important stuff 
} 

Wanted ситуация:

... WebServer 
_bus.Publish(new Message{Body="SomethingChanged"}; 

... Handlers (WebServers, WindowsServices etc) 
public void Handle(Message message){ 
    //Do important stuff 
} 
+0

Ну, может быть, вы могли бы - но трудно сказать, чего вы на самом деле пытаетесь достичь из своего описания - может быть, вы могли бы предоставить более подробную информацию о том, что вы пытаетесь сделать? – mookid8000

+0

Добавлен код, который может быть уточнен :) – Goblin

ответ

1

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

Не зная подробностей вашей проблемы, мое непосредственное чувство заключается в том, что вам будет лучше использовать какое-то общее постоянное хранилище для всего, что вы пытаетесь синхронизировать (a cache?), возможно, используя некоторую репликацию чтения, если вы хотите масштабировать и делать чтение очень быстрым.

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

  • Использование MongoDB (возможно, как точная копия устанавливается, если вы хотите масштабировать операции чтения) в качестве постоянного хранения вещи вы кэширование
  • Всякий раз, когда что-то происходит в вебе-приложении, bus.Send сообщения вашего бэкэнда
  • в вашем backend обработчик сообщений, вы обновляете Mongo (который автоматически будет реплицироваться для чтения подчиненных)
  • Всякий раз, когда вам нужно запросить данные, вы просто опрашивать множество Монго (используя slaveOk = верно, когда вы можете принять немного устаревшие значения)

причиной, почему я предлагаю это альтернативное решение, является то, что веб-приложение (по крайней мере, в среде .NET) имеют этот забавный переходный характер, когда IIS будет определять свой жизненный цикл, и в любой момент времени вы можете иметь n экземпляров. Это усложняет ситуацию, если вы держите в нем состояние. Это заставляет меня думать о веб-приложении как о клиенте, а не о издателе.

Простым решением является сохранение состояния в чем-то, что не приходит & go, например. базы данных.И причина, по которой я предлагаю Mongo, заключается в том, что я предполагаю, что вы беспокоитесь о том, что можете быстро обслуживать веб-запросы, но поскольку MongoDB довольно легко установить в качестве набора реплик, где операции чтения будут довольно быстрыми (и, более важно: горизонтально масштабируемое), я предполагаю, что эта настройка сделает все намного проще.

Как это звучит?

+0

Мои сообщения - это бизнес-события (обычно) -> например. «OrderId 4663 изменен - ​​новая версия: 4». Затем это событие транслируется во всех браузерах - это основано на этой информации. Моя проблема заключается в том, как подписаться на очередь, которая не принадлежит кому-либо (или имеет совместное владение). Веб-серверы не могут видеть друг друга (и не должны) – Goblin

+0

ах, в этом случае я думаю, что ваше текущее решение кажется разумным - я полагаю, что вы используете SignalR для вызова клиентов? Потому что в таком случае вы не могли бы установить «объединительную плату» SignalR (это то, что они называют :)) и просто иметь бэкэнд в составе одного концентратора SignalR? Таким образом SignalR будет отвечать за распространение обратного вызова всем клиентам через все доступные в настоящее время и подключенные веб-приложения. – mookid8000

+0

На самом деле мы используем WebSync (FrozenMountain), но тот же принцип :-). Я думаю, мы могли бы иметь часть сервера (например, объединительную плату SignalR) на отдельном сервере ... (могут быть некоторые проблемы https, но они должны быть управляемыми). Но спасибо за разъяснение :-) – Goblin

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