Понять, как ваша система выглядит с высоты

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

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

Архитектура пинбола?

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

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

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

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

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

Со временем, с постоянным развитием системы, Pinball Architecture может стать обузой. Возможные подводные камни:

  • Непреднамеренные побочные эффекты - если служба была создана с расчетом на то, что она будет использоваться определенными клиентами (что не является редкостью для монолитной миграции), но теперь принимает вызовы от нового клиента, может выполняться нежелательная логика, что приводит, например, к созданию неточных данных.
  • Условия состязания - если служба A вызывает службу B, затем службу C, а обе службы B и C вызывают службу D, что, если служба B имеет медленный день и вызов службы C поступает первым?
  • Проблемы с производительностью - при большей внутренней нагрузке из-за запросов, отправляемых по системе, вы довольно быстро обнаружите свои узкие места.
  • Неоптимальные затраты - вы можете решить некоторые проблемы с производительностью в облаке, потратившись на собственные средства (например, увеличив количество операций ввода-вывода в секунду при чтении в DynamoDB).

Так что рано или поздно вы почувствуете некоторую боль и решите уменьшить внутреннюю нагрузку на систему. Какая альтернатива?

Архитектура быстрого питания

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

Давайте разберемся с этим.

Приготовить и подарить (пищевой вариант)

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

  • Бургер-бургер будет готовить гамбургеры в ожидании, что кто-то скоро их закажет. Они собирают бургер с салатом и булочкой, упаковывают его в коробку и сдвигают по желобу, чтобы сделать его доступным для персонала, принимающего заказы.
  • Фургон с уличной едой, заполненный жареным картофелем, приготовит картофель вдвое или втрое, при этом последнему жареному потребуется всего несколько минут, чтобы доставить вкусный горячий жареный картофель. Горячие начинки будут производиться партиями и храниться в горячем состоянии для сборки. Начинки будут приготовлены в холодном / холодном виде, и они будут находиться в удобном доступе к серверу.
  • В рыночном ларьке, где подают паэлью, есть две готовые сковороды: одна уже приготовлена ​​и готова к подаче, а другая готова для приготовления следующей партии, когда первая сковорода будет частично продана.

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

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

Микросервисы для приготовления еды

Взаимодействие клиентов с вашими системами можно условно разделить на два типа:

  • Запросы данных - например, продукты по категориям, подробная информация о продукте, история моих заказов.
  • Запросы к действию - например, обновить мой профиль, добавить товар в корзину, оформить заказ

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

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

Подготовить и представить (системная версия)

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

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

Как мы это делаем?

Золотые правила для архитектуры быстрого питания

1. Сведите к минимуму выборку данных, пока клиент ожидает

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

Вот несколько вопросов, которые стоит задать себе:

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

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

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

2. Минимизируйте преобразование данных для ответа на запрос.

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

Еще вопросы, которые стоит задать себе:

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

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

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

Другие вещи, которые следует учитывать

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

Каковы требования к безопасности данных? Если вы переносите все эти бизнес-данные из серверной части и храните их рядом с клиентом, вы берете на себя ответственность за безопасность этих данных. Считать:

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

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

Пинбол или фастфуд?

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

Вы перешли на архитектуру быстрого питания? Если да, то я хотел бы услышать ваш опыт - хороший или плохой!