2016-01-04 3 views
0

Мы разрабатываем приложение, которое будет получать события из разных систем через очередь сообщений (Azure), но возможно, что некоторые события (сообщения) не будут поступать в порядке они были отправлены. Эти события будут получены и обработаны центральной системой на основе CQRS/ES, но я беспокоюсь, что если события помещаются в хранилище событий в неправильном порядке, мы получим мусор (например, «создать заказ» после «добавить элемент заказа» «).Может использоваться источник событий для устранения поздних прибывающих событий

Являются ли типичные системы ES, предназначенные для решения этой проблемы, или мы хотим обеспечить, чтобы такие сообщения были помещены в правильном порядке, прежде чем их вставляли в хранилище событий? Если у вас есть ссылки на статьи, которые поддерживают или просмотр, это поможет.

Редактировать: Я думаю, что мое описание явно слишком расплывчато, поэтому ответы, полезные в понимании CQRS/ES, не совсем отвечают на мою проблему, поэтому я добавлю немного более подробную информацию и, надеюсь, кто-то распознает проблему.

Во-первых, игроки.

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

Связывание склада с системой управления представляет собой довольно тонкое соединение Azure на основе облаков. Сообщения со склада отправляются на слой WCF/Soap в облаке, анализируются и отправляются по шине сообщений. Сообщение на склад отправляется по шине сообщений, а затем снова в облаке, преобразуется в вызовы Soap на сервер на складе.

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

Теперь, учитывая, что у нас есть порядковый номер в сообщениях, мы могли бы обеспечить, чтобы сообщения были возвращены в правильном порядке, прежде чем они будут отправлены в систему CQRS/ES, но мои вопросы, это необходимо, может ли ES фактически использоваться для изменения порядка событий в логическом порядке, в котором они были предназначены?

+0

Являются ли события, генерируемые различными источниками? например событие 'OrderCreated' генерируется другим источником, чем событие' OrderItemAdded' и в разное время? –

+1

Для до и после событий, см. Сообщение Грега Янга по этому вопросу http://goodenoughsoftware.net/2014/03/02/event-sourcing-and-postpre-dated-transactions/ –

ответ

0

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

События из нескольких агрегатов не должны заботиться о заказе из-за транзакционных гарантий совокупности.

Заканчивать http://cqrs.nu/Faq/aggregates, http://cqrs.nu/Faq/command-handlers и связанные с ним часто задаваемые вопросы

Для интро к ES и оптимистической блокировки, смотрите на http://www.jayway.com/2013/03/08/aggregates-event-sourcing-distilled/

+0

Спасибо за ваш ответ Карл, события отправляются с веб-сайта, который берет заказы клиентов и склад, который выполняет эти заказы. Принимаются некоторые решения. Я не уверен, как обращаться, например, клиент может изменить заказ до момента, когда склад начнет выполнять этот заказ, но эти два события могут теоретически перекрываться. Проблема не в том, что на складе или на веб-сайте есть транспорт (Azure Service Bus), который не гарантирует, что сообщения поступят в том порядке, в котором они отправлены. – naskew

1

Каждое сообщение, приходящее в Service Bus помечен SequenceNumber. SequenceNumber является монотонно увеличивающейся беззеркальной 64-битной целой последовательностью, привязанной к очереди (или теме), которая обеспечивает абсолютный критерий порядка по прибытии в очередь.Этот заказ может отличаться от порядка доставки из-за ошибок/прерываний и существует, чтобы вы могли восстановить порядок прибытия.

Две функции в Service Bus, специфические для управления порядка внутри очереди:

  1. Сессии. A sessionful queue помещает блокировки во все сообщения с тем же свойством SessionId, что означает, что FIFO гарантируется для этой последовательности, так как никакие сообщения в последовательности не доставляются до тех пор, пока «текущее» сообщение не будет обработано или оставлено.
  2. Отсрочка. Defer method оставляет сообщение в стороне, если сообщение не может быть обработано в это время. Сообщение может быть позже be retrieved by its SequenceNumber, которое тянет из скрытой очереди отсрочки. Если вам нужно место для отслеживания того, какие сообщения были отложены для сеанса, вы можете поместить структуру данных, содержащую эту информацию right into the message session, если вы используете сеансовую очередь. Вы можете затем pick up that state again elsewhere on an accepted session, если вы, например, не выполняете обработку на другой машине.

Эти функции были созданы специально для документооборота в Office 365, где порядок явно имеет значение совсем немного.

+0

Клеменс, спасибо. Я думаю, вы предлагаете нам исправить порядок, прежде чем использовать сообщения и за что я согласен. Однако другие не согласны с ними, и фактически они делают то, что в облаке существует несколько отправителей, поэтому исходный порядок сообщений может быть потерян. – naskew

+1

«Правильный» порядок сообщений всегда зависит от какого-то контекста. Для некоторых это абсолютный порядок прибытия в очередь. Если вы заботитесь о заказе, связанном с создателем или субъектом, используйте сеансы (sessionid идентифицирует отправителя/субъекта). Если вам нужен порядок, связанный с внешним контекстом, которым вы управляете (например, рабочий процесс), а также с несколькими отправителями, отправляйте «ранние» сообщения обратно в очередь/подпрограмму с отсрочкой и извлекайте их, когда это их очередь, т. Е. Сортировать поток сообщений на стороне приема. [Я работаю на Service Bus, FWIW] –

1

Я бы прокомментировал ответ KarlM, но StackOverflow не позволит, так что здесь идет ...

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

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

Чтобы быть полностью распространенным: если вы хотите предоставить их на веб-сайт, то на складе необходимо спросить, может ли он начать выполнять заказ. Если вы хотите предоставить их на склад, веб-сайт должен спросить, может ли он отменить заказ.

Надеюсь, что это полезно.

+0

Саймон, это, безусловно, верно, и у нас были разговоры по этим строкам здесь. Вероятность заключается в том, что у нас будет система, в которой склад сообщает, что он выполняет заказ, и веб-сайт будет отображать заказы как заблокированные, как только начнется выполнение. Однако существует вероятность, что редактирование начинается до блокировки и отправляется после этого, в этом случае пользователю будет сообщено, что его невозможно было отредактировать. – naskew

+0

Если вы можете реализовать шаблон запроса/ответа для вызова веб-сайта, я думаю, что все в порядке. Компромисс заключается в том, что клиентская система должна ждать ответа до подтверждения действия. –

0

Вы говорите: «Эти события будут получены и обработаны центральной системой на основе CQRS/ES, но я беспокоюсь, что если события будут помещены в хранилище событий в неправильном порядке, мы получим мусор (например «создать заказ» после «добавить элемент заказа») ». Кажется, что возникает недоразумение о том, что такое шаблон CQRS с Event Sourcing. Проще говоря, Event Sourcing означает, что вы изменяете Агрегаты (согласно терминологии DDD) с помощью встроенных событий, то Агрегатная настойчивость представлена ​​событиями, а Агрегат может быть восстановлен путем повторного воспроизведения событий. Это означает, что область действия довольно мала, сама Агрегат. Теперь CQRS с Event Sourcing означает, что эти события из Aggregates публикуются и используются для создания прогнозов Read или других моделей домена, которые имеют разные цели. Так что я действительно не понимаю ваш вопрос, учитывая приведенные выше объяснения.

, связанный с заказом:

  • уже есть ответ упоминая оптимистическую блокировку, поэтому события, генерируемые внутри одного агрегата должны быть заказаны и оптимистичный замком является решением
  • событий Чтения обработки проекции в порядке. Решение, которое я использовал в прошлом, состояло в том, чтобы публиковать события на RabbitMQ и обрабатывать их со Storm. У RabbitMQ есть некоторые гарантии при заказе, и у Storm есть некоторые функции сродства обработки. Для Storm (насколько я помню) вы можете указать, что для данного идентификатора (например, Агрегатный ID) будет использоваться один и тот же обработчик, поэтому события обрабатываются в том же порядке, который получен от RabbitMQ.
0

В статье на MSDN https://msdn.microsoft.com/en-us/library/jj591559.aspx государства «Хранимые события должны быть неизменны и всегда считываются в том порядке, в котором они были сохранены» в разделе «Производительность, масштабируемость и последовательность». Это явно означает, что приведение событий в порядок не допускается. В той же статье также говорится несколько раз, что, хотя события не могут быть изменены, могут быть сделаны корректирующие события. Это будет означать, что события обрабатываются в том порядке, в котором они получены, чтобы определить текущую истину (состояние совокупности). Я пришел к выводу, что перед отправкой событий в хранилище событий мы должны устранить проблему с порядком обмена сообщениями.

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

  • Нет связанных вопросов^_^