Как вписать механизм правил в микросервисную архитектуру, когда она требует много входных данных?


12

Текущая ситуация

Мы внедряем (и в настоящее время поддерживаем) веб-приложение для онлайн-покупок в микросервисной архитектуре.

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

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

На данный момент наш shopping-cartмикросервис собирает все эти данные из других микросервисов. Несмотря на то, что часть этих данных используется shopping-cart, большую часть времени они в основном используются для подачи механизма правил.

Новые требования

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

Продолжая, как есть, мы столкнемся с несколькими проблемами:

  • каждый (вызывающий механизм правил) должен переопределить выборку данных, даже если им это не нужно для себя;
  • запросы к движку правил сложны;
  • продолжая в этом направлении, нам придется передавать эти данные по всей сети для многих запросов (представьте, что μs A вызывает μs B, вызывающий механизм правил, но у A уже есть некоторые данные, необходимые механизму правил);
  • shopping-cart стал огромным из-за всей выборки данных;
  • Я, наверное, забыл много ...

Что мы можем сделать, чтобы избежать этих неприятностей?

В идеале мы бы не добавляли больше сложности в механизм правил. Мы также должны убедиться, что это не становится узким местом - например, некоторые данные довольно медленно выбираются (10 с или даже больше), поэтому мы реализовали предварительную выборку shopping-cartтаким образом, чтобы данные с большей вероятностью находились там до того, как мы вызовем правила двигатель, и сохранить приемлемый пользовательский опыт.

Некоторые идеи

  1. Позвольте механизму правил получать нужные ему данные. Это добавило бы еще большей сложности, нарушив принцип единой ответственности ( еще больше… );
  2. Внедрите прокси μ перед механизмом правил для извлечения данных;
  3. Реализуйте «сборщик данных», который механизм правил вызывает для извлечения всех данных, которые ему нужны одновременно (составной запрос).

Позвольте мне подвести итог (с вопросами): у вас есть несколько микросервисов, реализованных для магазина. Одним из них является корзина для покупок . В корзину встроен механизм правил (доморощенный или какой-то продукт), верно? Когда пользователь добавляет товар в корзину, механизм правил запускается как часть бизнес-логики и как-то модифицирует корзину (например, товары со скидкой или комплектные товары), верно? Теперь другой микросервис также хочет использовать правила, которые могут основываться на аналогичных входных данных, верно? А входные данные предоставляются другими микросервисами, верно? Почему выборка данных так сложна?
Энди

3
Лучший способ избежать этих неприятностей - избавиться от механизма правил.
whatsisname

@Andy Механизм правил - это отдельный микросервис. Его API немного адаптирован shopping-cart, но мы можем довольно легко адаптировать его для нужд других микросервисов (они по-прежнему связаны с пользователями, продуктами и заказами). Как мы видим, они будут нужны одни и те же входные данные, тем более, что бизнес способен выбрать предикаты применить. Все данные предоставляются другими микросервисами, кроме самого содержимого корзины. Извлечение данных само по себе не сложно, но становится сложным, когда вам нужно вызвать ~ 10 других микросервисов и поддерживать структуру, ожидаемую механизмом правил.
Дидье Л

@whatsisname Я тоже не большой поклонник механизма правил, но в настоящее время мы имеем дело с ним и так или иначе, и бизнес меняет свою конфигурацию на ежедневной основе. Даже если бы мы избавились от этого, нам все равно понадобился бы какой-нибудь настраиваемый компонент, чтобы сделать то же самое, требуя одинаковых входных данных… Это все равно был бы механизм правил, просто с другим именем, и мы все равно столкнулись бы с теми же проблемами.
Дидье Л

Ответы:


8

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

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

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

каждый (вызывающий механизм правил) должен переопределить выборку данных, даже если им это не нужно для себя;

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

Вопрос межсервисного общения сам по себе не является «решенной» проблемой, но на данном этапе это также не проблема «накатить свои собственные». Множество существующих инструментов и стратегий могут сделать вашу жизнь намного проще.

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

Большинство ваших проблем проистекает из этого.

запросы к движку правил сложны;

Сделайте их менее сложными.

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

Определите какой-то протокол для ваших данных. Я предполагаю, что у вас, ребята, нет определенного плана API (как указано выше), и вы начали писать вызовы REST ad hoc всякий раз, когда это необходимо. Это становится все более сложным, так как теперь вы должны поддерживать каждый микросервис каждый раз, когда что-то обновляется.

Более того, вы не совсем первая компания, которая когда-либо внедрила инструмент для онлайн-покупок. Иди исследуй другие компании.

Что теперь...

После этого вы по крайней мере справились с некоторыми из самых больших проблем.

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

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

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

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

Мы также должны убедиться, что это не становится узким местом - например, некоторые данные загружаются довольно медленно (10 с или даже больше)

Предполагая, что эта проблема существует после решения вышеупомянутых проблем, вам нужно серьезно расследовать, почему это происходит. У вас разворачивается кошмар, но вместо того, чтобы выяснить, почему (10 секунд? Для отправки данных портала покупок ? Назовите меня циничным, но это кажется немного абсурдным), вы, кажется, исправляете симптомы, а не смотрите на проблему, вызывающую симптомы в первое место.

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

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

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

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


Спасибо за ваш ответ, @enderland. Действительно, архитектура микросервиса все еще относительно нова для нас, отсюда и этот вопрос. Этот механизм правил эволюционировал немного органично, чтобы привести нас сюда, поэтому сейчас нам нужны направления движения, чтобы это исправить. Это (к счастью) полностью не сохраняющее состояние, поэтому количество данных, которые он принимает в качестве входных данных. И это то, что мы хотели бы решить в первую очередь, чтобы сделать его компонентом многократного использования. Но как уменьшить количество входных данных без уменьшения количества доступных предикатов? Я предполагаю, что нам нужен API, который может извлекать данные самостоятельно, но как правильно его спроектировать?
Дидье Л,

Что касается проблем с производительностью, то они связаны с микросервисами, которые на самом деле вызывают медленные сервисы JMS и SOAP, реализованные внутренними серверами. У них есть свои собственные базы данных, но производительность не является их первой целью (если она справляется с нагрузкой). И их слишком много, чтобы подумать о репликации своих данных и их сохранении (хотя для некоторых мы это делаем). Лучшее, что мы можем сделать - это кэширование и предварительная выборка.
Дидье Л

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

1

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

Текущие потребители механизма правил могут передать процесс сбора необходимой информации более специализированному компоненту.

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

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

У меня было бы два отдельных сервиса для этого. Каждый из них будет полагаться на правила обслуживания двигателя для некоторых его тяжелых работ. Каждый из них будет собирать необходимые данные, необходимые для запроса к механизму правил.

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


0

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

В качестве практического вопроса для реализации я упомяну, что IBM Operational Decision Manager начинает документировать и уже поддерживает использование продукта в док-контейнерах . Я уверен, что другие продукты также обеспечивают эту поддержку и что она станет основной.


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.