Выборочное чтение из очереди - пользовательская служба MSMQ, ESB или что-то еще? - PullRequest
2 голосов
/ 23 августа 2010

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

Вот (надеюсь) очень простое и концептуальное описание того, что должна делать система:

У меня есть служба, которой клиенты могут отправлять сообщения. Служба - «Огонь и забудь» - самое большее, что мог бы получить клиент, - это то, что может означать успех или неудачу (успех - это получение сообщения).

Обработка / обработка каждого сообщения нетривиальна и может занимать значительные системные ресурсы. По этой причине одновременно могут обрабатываться только X-сообщения, где X - настраиваемое значение (на основе системных характеристик и т. Д.). Входящие сообщения будут храниться в очереди до тех пор, пока не наступит «их очередь».

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

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

Является ли ESB неподходящим инструментом для работы? Есть ли какая-то другая технология или шаблон, на который я должен смотреть?

Обновление

Несколько уточнений.

Относительно обработки сообщений «по порядку» - в контексте одного клиента сообщения должны обязательно обрабатываться в порядке их получения. Сложно объяснить точные причины этого, но это жесткое требование. Я не упомянул, что только одно сообщение для каждого клиента будет обрабатываться одновременно. Поэтому, даже если бы было 10 рабочих потоков и только один клиент имел сообщения, ожидающие обработки, только одно из этих сообщений было бы обработано за один раз - не было бы никакого беспокойства о состоянии гонки.

Я полагаю, что это обычно возможно с ванильным MSMQ - вы можете иметь список сообщений в очереди и всегда сначала брать самое старое.

Я также хотел уточнить пример использования для заказа кругового робина. В этом примере у меня есть два клиента (A и B), которые отправляют сообщения, и только один рабочий поток. Все очереди пусты. Клиент А потерял связь за одну ночь, поэтому в 8 утра отправляет 1000 сообщений в службу. Эти сообщения помещаются в очередь, и рабочий поток берет самое старое и начинает обрабатывать его. Когда это первое сообщение обрабатывается, клиент B отправляет сообщение в службу, которая ставится в очередь (как отмечено, вероятно, в отдельной очереди). Когда первое сообщение клиента A завершает обработку, логика должна проверить, есть ли у клиента B сообщение (это «очередь» клиента B), и, поскольку оно его находит, обрабатывает его следующим.

Если бы клиент B не отправил сообщение в течение этого времени, рабочий продолжил бы обрабатывать сообщения клиента A по одному, всегда проверяя после обработки, чтобы видеть, содержали ли другие очереди клиента ожидающие сообщения, чтобы гарантировать, что ни один клиент не голодал .

Там, где я все еще чувствую, может быть несоответствие между ESB, и эта проблема заключается в том, что ESB предназначен для облегчения связи между службами; я пытаюсь достичь сочетания обмена сообщениями / связи и системы выборочного обслуживания.

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

Таким образом, система должна будет иметь возможность запрашивать очередь для определенного клиента,

Поиск в очереди MSMQ сообщения от определенного клиента с использованием курсоров может быть неэффективными не масштабируется.

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

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

[[Я не говорю «переместить» сообщения, поскольку вы не можете сделать это с помощью кода приложения;Вы можете только прочитать сообщение и создать новое сообщение, используя исходные данные.Это различие важно, например, когда вы используете Source Journaling.]]

Cheers

John Breakwell

2 голосов
/ 23 августа 2010

Использование ESB, такого как NServiceBus, кажется хорошим решением вашей проблемы.Но исходя из вашего концептуального описания, есть несколько вещей, которые следует учитывать.Давайте пошагово рассмотрим ваши требования, используя NServiceBus в качестве возможного решения ESB:

У меня есть служба, в которую клиенты могут отправлять сообщения.Служба - «Огонь и забудь» - самое большее, что мог получить клиент, это что-то, что может означать успех или неудачу (успех, если сообщение было получено).,Вы можете Bus.Send (сообщение) от клиента.Если ваш клиент требует ответа, вы можете использовать Bus.Return (ErrorCode).Вы упоминаете, что «успех в том, что сообщение было получено».Если вы используете ESB, например NServiceBus, доставит сообщение на платформу обмена сообщениями.Таким образом, если ваш Bus.Send не выдает исключение, вы можете быть уверены, что сообщение было отправлено правильно.Из-за этого вам, вероятно, не нужно отправлять сообщения об успехе / неудаче обратно клиенту.

Обработка / обработка каждого сообщения нетривиальна и может занимать значительные системные ресурсы.По этой причине одновременно могут обрабатываться только X-сообщения, где X - настраиваемое значение (на основе системных характеристик и т. Д.).Входящие сообщения будут храниться в очереди до тех пор, пока не будет обработана их очередь.

При использовании NServiceBus вы можете настроить количество рабочих потоков, установив опцию «NumberOfWorkerThreads».Если ваш сервер имеет несколько ядер / процессоров, вы можете использовать этот параметр для балансировки рабочей нагрузки.

Для каждого клиента сообщения должны обрабатываться по порядку (FIFO).

Это может вызвать проблемы в зависимости от ваших требований.ESB в целом не обещают обрабатывать сообщений в порядке , если в них много потоков, работающих с сообщениями.В случае NServiceBus вы можете отправить массив сообщений от клиента в шину, и они будут обработаны по порядку. Кроме того, вы можете решить некоторые проблемы обмена сообщениями по порядку, используя Sagas .

Однако некоторые клиенты могут отправлять много сообщений подряд (тысячи или более), например, если они потеряли соединение на некоторый период времени

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

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

Это не проблема, потому что вы решили использовать сообщения:)

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

Не могли бы вы расширить это?Я не уверен в твоем дизайне.

...