MS Azure: хранение данных в разных местах, в зависимости от пользователя

Привет!

Используется Azure для хостинга приложений и инфраструктуры.

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

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

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

Но возникает теперь вопрос: как сделать так, чтобы фронтенд обращался к нужному эзкмпляру бекенда?

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

1. Извлекать информацию из JWT токена; потенциально любую, но для данного случая, ИД пользователя будет достаточно;

2. Лазить куда-то (в БД; в Редис; и т.п.), извлекать какие-то данные для принятия решений; в данном случае нужно откуда-то взять регион пользователя;

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

если регион = "уа" тогда



    погнали сюда



если регион = "америка" или регион = "канада" тогда



   погнали сюда



если ничего из вышеперечисленного не сработало тогда



   погнали сюда

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

Какие ещё есть для этого варианты в Azure?

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Если не секрет, к какому решению в итоге пришли (наверное, лучше в личку)?

Ни к какому. У этой штуки вскоре после того, как я тут спросил, сменился приоритет и решили, что вернемся к этому попзже.

Что-то типа такого?

learn.microsoft.com/...​-private-sql-multi-region

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

Мы же тут не знаем всех требований. Ни частоты запросов, ни обьема хранимых данных, ни требований к их локальности (т.е. должны ли они и хранится и обрабатываться в регионе, или важно именно хранение).
Так что вариантов куча. От самого лобового — на фронтэнде решать куда именно он будет ходить за данными, до кастомного сервиса-прослойки на YARP который будет рероутить запросы на нужный бэкэнд, ну или свой слой хранения который будет отдавать соедиение с нужной БД.
Если траффик не слишком большой, а программировать лень — я бы вообще вывесил наружу инстанс(ы) Azure API Management с роутингом запроса на уровне политики APIM. Т.е при логине пользователю отдается токен с клаймом в котором указан его регион, а потом APIM роутит запросы.

на фронтэнде решать куда именно он будет ходить за данными

Мне не очень нравится идея «на фронтенде решать», поэтому я такой вариант пока для себя не рассматриваю даже.

до кастомного сервиса-прослойки на YARP который будет рероутить запросы на нужный бэкэнд

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

свой слой хранения который будет отдавать соедиение с нужной БД

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

Если траффик не слишком большой, а программировать лень — я бы вообще вывесил наружу инстанс(ы) Azure API Management с роутингом запроса на уровне политики APIM. Т.е при логине пользователю отдается токен с клаймом в котором указан его регион, а потом APIM роутит запросы.

За 24 часа 130 Гб исходящего и 18 Гб входящего тафика, цифры будут расти. Это много или нет в данном случае?
Вообще что-то типа такого я бы и хотел сделать. В идеале я изначально хотел, что бы это «что-то» по ИД из токена доставало откуда-то регион, но по большому счету можно в токен и регион запихнуть. Посмотрю поближе на этот APIM. Спасибо!

Откуда-то доставать регион по токену — это на каждый запрос куда-то ходить. Еще одна задержка и еще одна точка отказа.

Много или нет — не скажу. Я знаю только про лимиты на количество запросов в секунду.

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

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

Спасибо за ответ! По вашему описанию выглядит как то, что я искал.

Что в данном случае «слой»? Отдельное приложение, через которое делать все вызовы к БД?

В целом да. В принципе, эта же идея у тебя самого была:

это должен быть какой-то «маршрутизатор» (прокси сервер)

Только я его предлагаю расположить «за» бекендом и сделать максимально простым: никакой логики кроме маршрутизации, никаких походов в какие-то ещё источники данных.

А как эти приложения будут между собой комуницировать, через http? Если да, то при необходимости поменять что-то в SQL запросе, например, добавить просто поле в выборку, это надо будет делать согласованно в двух приложениях: сначала в «СКЛ-прокси» добавить и выставить наружу, потом в «бекенде» сделать его получение и обработку. Или я что-то неправильно понял?

Коллеги, я опять влезу :-)

А как эти приложения будут между собой комуницировать, через http?

Если на .NET стеке то можно посмотреть на GraphQL в качестве протокола связи. Если использовать тот же HotChocolate для имплементации, то в принципе «добавление поля» в «СКЛ-прокси» будет безболезненным и не будет ломать существующие клиенты. Более того, этот прокси не будет запрашивать это поле из БД и/или пихать его в сеть если на то не будет запроса от клиента.

Ну и естественно в запросе можно передавать условия фильтра и сервер будет сам преобразовывать их в EF запрос.

Добавление поля ничего не сломает и в случае обычного REST. В случае с GQL, как и в случае с REST, все равно придется делать добавление поля в двух местах и согласованно: описать его в сервисе с GraphQL API (оно же само по себе там не появится) и только после этого вы сможете его потреблять в другом сервисе. Или вы предлагаете выставлять сущность БД в полностью том виде, как она есть? Также в варианте с GQL не получится (или я не знаю как) сделать группировки, например, или произвольные соединения между таблицами (если нету внешнего ключа, например; к сожалению, бывает и такое). Для простых сценариев GQL выглядит прикольно, но когда сценарий начинает быть чуть сложнее, чем простой, там уже могут возникать сложности. Ну и в принципе выставлять всю БД через GQL API мне потенциально стремно концептуально, не говоря уже о том, что это все надо описать в виде GQL запросов. Хотя может можно написать код, который будет это все выставлять автоматически, отталкиваясь от модели БД. Но тем не менее, концептуально мне такое всетаки как-то стремно делать.

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

Мне кажется, вариант, со своим прокси приложением ДО основного бекенда выглядит понятнее и проще. Или это кажется?

Ну да, вариантов много можно придумать. Предложенный Антоном довольно толковый. Возможно, в конкретных условиях можно будет пойти на какие-то компромиссы и, например, «добавлять поле» в двух местах будет приемлемым вариантом. Возможно вообще надо только любым способо перевести коммуникацию в HTTP, а направление в нужную базу сделает инфраструктура, скажем, на основе хедера (я не специалист в Azure, но наверняка там есть аналог AWS Application Load Balancer).

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

Ще може буть Azure Traffic manager , якщо Front door не підходить

Підписатись на коментарі