шаблоны очередей сообщений - PullRequest
1 голос
/ 06 августа 2009

У нас есть две части архитектуры. По сути, они образуют производителя и потребителя. Часть 1 (p1) публикует сообщения для части 2 (p2), которая обрабатывает сообщение, этот процесс включает в себя отправку сообщения на удаленный узел, который должен подтвердить сообщение после того, как обработал его, этот процесс может в лучшем случае занять несколько секунд.

p2 имеет конечную длину в своей очереди, и элементы не удаляются, пока не получит подтверждение от удаленного узла. Благодаря этому p2 может возвращать ответ QUEUE_FULL на p1. Когда p1 получает этот ответ, он сохраняет очередь, всякий раз, когда создается новое сообщение, он добавляет его в конец этой очереди и затем циклически перебирает очередь, отправляющую сообщения на p2, пока он снова не получит QUEUE_FULL. Проблема здесь в том, что, когда очередь p2 пуста / имеет место, она не может уведомить p1 о создании сообщений.

Для каждого экземпляра производителя в p2 есть соответствующий производитель в p1, это важно, когда речь идет о возможных решениях ниже.

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

Другое решение может состоять в том, что p1 можно изменить, чтобы продолжать пытаться отправить сообщение на p2. Проблема заключается в том, что у производителя в p1 должен быть поток, который спит x, прежде чем пытаться отправить следующее сообщение, очевидно, что может существовать синглтон, который обрабатывает этот механизм ожидания / повторной попытки, однако логика здесь, поскольку производители и потребители увеличиваются до много тысяч, становится довольно сложным;

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

Я близок к предложению уровня MQ, где p1 публикует и p2 читает. Однако это приводит к появлению новой проблемы, когда p2 не может уведомить p1, когда удаленный узел уходит, однако это может быть обработано обратным вызовом http от p2 к p1 - уровень служебных данных здесь приемлем как вероятность того, что удаленный узел выйдет далеко низко.

Я пропустил шаблон проектирования, который устранял бы необходимость в MQ (еще одна служба, о которой нужно беспокоиться, отслеживать и т. Д.)? Мысли высоко ценится.

Некоторые другие детали:

  • каждый экземпляр производителя p1 по большей части является областью запроса
  • каждый потребитель p2 является выделенным запущенным потоком

Ответы [ 2 ]

3 голосов
/ 06 августа 2009

Mike

Кажется, что процесс имеет значительную сложность (с возможностью введения большего количества), просто чтобы избежать использования MQ? Может быть много причин, чтобы НЕ использовать MQ, стоит мой опыт, но если у вас есть доступ к нему, используйте его с полной отдачей! :) Наблюдать за новым процессом MQ гораздо проще, чем писать код для введения аналогичных возможностей.

В идеале надежная очередь не позволит P1 когда-либо действительно знать о P2 или его статусе.

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

Это также вносит дополнительную сложность - вы знаете свою среду, но это может привести к таким вопросам, как «почему я больше не получаю сообщения?» - оказывается, что служба автономно закрывает другую службу. Если все сделано правильно, это потрясающе и облегчает бремя поддержки для операторов - если все сделано неправильно, это только увеличивает бремя поддержки. Никто не любит этого парня.

Не могли бы вы также поставить в очередь на уровне данных, где хранилище для P2 может быть не такой большой проблемой?

Охватить очередь (MQ, MSMQ, Sql Queue)!

Z

1 голос
/ 06 августа 2009

Возможность просмотра 3

  • Как насчет открыть еще один MQ для служебных команд (вместо вызовов http);
  • считают p2 многопоточным, когда один поток без ожидания извлекает сообщения из MQ и помещает их в другой поток для обработки;
  • (!) Использовать транзакционную версию MQ - чтобы p2 мог извлекать сообщения немедленно, а p1 мог размещать его так быстро, как только мог. Но если обработка не удалась, очередь будет откатана.
...