Есть SaaS проект, нужно его монетизировать, организовать биллинг. Будут подписки, счета, платежи.
При каждом запросе пользователя на бекенд нужно проверять, доступно ли пользователю запрашиваемое действие. А это либо дополнительный запрос (а то и несколько) в БД (если по старинке), либо организовать сервис, который, условно, держит все у себя в памяти и быстрее даст ответ. На такой сервис, кроме проверки подписки, можно переложить задачи по генерации счетов, учета платежей и прочих задач, связанных с деньгами.
Но вот проблема: допустим, я вынесу весь биллинг в отдельный сервис; но в админке у нас есть различные отчеты, которые будут затрагивать и основные данные, и данные биллинга (например, сколько денег пришло за сентябрь от клиентов из Москвы). Получается, придется либо придумывать адский алгоритм (взять клиентов Москвы из основной БД, затем через API к сервису биллинга запросить платежи по списку, потом еще как-то найти сумму, сгруппировать и т.д), либо все-таки хранить данные билинга в общей БД и быстро строить отчеты стандартными запросами. Но в этом случае сервис получается как бы и не сервис, т.к. он не изолирован. А раз это больше не сервис, то зачем на него переносить задачи по добавлению платежей, тем более, если все в одной БД - достаточно все действия в модуль основного приложения сделать.
И вот по этой логике получается, что будет у меня простой сервис, который просто проверяет текущие подписки и использует БД и вообще все данные основного приложения.
Вот такие мысли у меня. Скажите, я правильно рассуждаю, или есть другие варианты?
Роман Мирр, Логику в принципе описал в вопросе - если делать в лоб, то перед каждым запросом юзера нужно будет делать запрос в БД, чтобы определить, доступно ли по тарифу этому юзеру действие. То есть увеличится количество запросов к БД существенно. А можно держать какой-то кеш в памяти, и для определения параметров тарифа обращаться к нему. Но процессов-бекендов у меня много (бекенд на ноде), а этот кеш должен быть один. Это либо какое-то хранилище использовать (Redis, memcache и т.д.), либо выделить все в один процесс и внутри него организовать кеш. В первом случае все равно нужно как-то управлять кешем, с помощью какого-то процесса. Вот я и остановился на втором варианте - сделать сервис, который будет отвечать на вопросы биллинга. Но кеш же нужно своевременно обновлять (например, когда оплата прошла), поэтому логично и оплату вносить через этот сервис - он сразу сможет обновить данные по нужному клиенту. А где оплата, там и счета и все остальное. Вот так. Вроде логично.
Я вполне допускаю, что это не микросервисная архитектура, а просто монолит с выделенным сервисом. Готов выслушать мнение опытных.
Дмитрий Скрябин, в целом, согласен с вышенаписанным.
Redis - вполне хорошее и рабочее решение для кэширования данных. Разумеется, 1 общий кэш на все сервисы.
Если вы не знаете как разделить эти сервисы то это значит что вы пока не определились с главным - не составили список use case'ов, которые реализует ваш новый биллинг и не составили список сущностей, которыми представлена новая система. Начните отсюда, а там станет понятнее какие данные в каком виде и как должны транслироваться
по базам разносят не из-за моды (хотя хипстеры могут), а из-за нагрузки, секурности, отказооустойчивости и проч.
биллинг всегда (ну или до первого взлом / дропа базы) отдельный сервис - это деньги, это обязательства, с куда более кратным резервированием и бэкапами
Ну и, вообще, все данные в базе - это обязательства, потому что если не будет основных данных, то сам биллинг делу не поможет. Бекапы нужны (и делаются) на все БД.
Сразу предупреждаю что не работал с системами биллинга вплотную.
Микросервисы
Микросервисы помимо всего привносят дополнительную модульность к общей архитектуре. Система биллинга вряд ли может быть представлена микросервисом. На микросервисах лежит малое количество функций, иначе они не микро.
Архитектура
... если делать в лоб, то перед каждым запросом юзера нужно будет делать запрос в БД, чтобы определить, доступно ли по тарифу этому юзеру действие. То есть увеличится количество запросов к БД существенно. А можно держать какой-то кеш в памяти, и для определения параметров тарифа обращаться к нему. Но процессов-бекендов у меня много (бекенд на ноде), а этот кеш должен быть один. Это либо какое-то хранилище использовать (Redis, memcache и т.д.), либо выделить все в один процесс и внутри него организовать кеш. В первом случае все равно нужно как-то управлять кешем, с помощью какого-то процесса. Вот я и остановился на втором варианте - сделать сервис, который будет отвечать на вопросы биллинга. Но кеш же нужно своевременно обновлять (например, когда оплата прошла), поэтому логично и оплату вносить через этот сервис - он сразу сможет обновить данные по нужному клиенту. А где оплата, там и счета и все остальное.
Конечно нельзя по любому запросу пользователя лезть в БД и всё заново. Можно периодически отложенно считать стоимость услуг и сливать результаты в кэш.
Биллинг может состоять из нескольких микросервисов, например. Тут все зависит от деталей. В общем, в этом и состоит одна из главных задач в архитектуре - настроить потоки взаимодействия
Роман Мирр Спасибо за ссылку, полезно. Вот там как раз биллинг отдельно. Значит, я на правильном пути в отношении выноса биллинга. Иван Шумов согласен, что нужно архитектуру продумывать, поэтому и задал этот вопрос :) Не понимаю, как построить взаимодействие, когда один сервис (сервис отчетов) требует данные от нескольких других сервисов (биллинг, клиенты,..). Тогда либо дублировать данные в сервисе отчетов, либо давать доступ в БД других сервисов, либо тянуть от каждого сервиса данные по API и обрабатывать их (но тут уже sql не получится использовать).
Благодаря вашим ответам все немного проясняется для меня. Есть еще над чем подумать.