Что из этого будет правильным/компромиссным архитектурным решением?

У компании есть своя программа (ERP система), которая работает с удаленными базами MySQL, отдельными на каждого клиента. Теперь занимаемся разработкой CRM системы, которая будет тесно связана с ERP, но уже в вебе. Т.е. получается, что нужно каким-то образом втиснуть архитектуру CRM в то, что уже было до этого и сильно не потерять.

По сути вижу такие варианты:
1. Ничего не менять и реализовывать CRM на отдельных базах для каждого клиента с одним бекендом.
Т.е. каждый запрос мы проверяем к какой компании относится юзер, находим данные его базы, подключаемся, делаем что нужно и возвращаем ответ. При таком решении я вообще сомневаюсь в возможности нормально все это поддерживать в будущем (клиентов уже около 500) и в возможности системы справиться с нагрузками (получается бекенд каждый запрос будет заново коннектится к базе данных). Еще один минус - все базы удаленные, т.е. + время на отправку запроса в БД, а если они последовательные, то время растягивается до 5-10 секунд на ответ, но это еще как-то решаемо.

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

3. Для каждого клиента разворачивать отдельный бекенд и БД в контейнере. Реализовать средства мониторинга для поддержки, автоматического обновления и т.д. Но тут тоже сильно усложняется поддержка всей системы.

Нужен совет. Все решения имеют свои плюсы и минусы в краткосрочном и долгосрочном плане. Спасибо!
  • Вопрос задан
  • 495 просмотров
Решения вопроса 1
К сожалению, нет данных, почему базы удаленные и разделены на несколько. Это сильно влияет на ответ. Может быть это хотелка ваших клиентов, чтобы все данные хранились именно на их базах? Или по юридическим соображениям. Тогда имеет смысл вариант 3 — вы просто продаёте комлексный self-hosted продукт. Не думаю, что для админов составит много труда настроить системы мониторинга, сбора логов и бэкапа. Один раз написать скрипты и потом это автоматизировать.

Но если считать, что никаких ограничений нет, то я за вариант 2. Логичнее всего иметь одну базу, где каждая сущность имеет client_id, а в коде на уровне базовых классов ORM добавить фильтр по нему. С серверной стороны — шардинг по client_id:
— Всё будет работать быстро и масштабироваться горизонтально по мере роста клиентов
— Придётся архитектурно немного заморочить, но имхо меньше, чем в предложенных вами вариантах
— Можно иметь общий дефолтный ACL для всех клиентов с возможностью кастомизации для каждого из них (уверен, что это понадобится)
— Все данные в одной базе и при желании вы сможете сделать дэшборд для супер-админа, который будет уметь редактировать всё это хозяйство по всем клиентам сразу и онбоардить нового клиента: создать входной аккаунт для админа клиентской компании, установить дефолтные настройки и определить доступный набор фич. Если такое планируется, советую сразу продумать архитектуру, иначе будет потом крайне больно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Можно сделать п.2, но так, что в программе ничего не нужно будет менять.
Ответ написан
zoonman
@zoonman
⋆⋆⋆⋆⋆
Логичнее всего иметь одну базу для всех клиентов.
Разумно было бы держать какой-то идентификатор клиента в таблицах.
Например создать таблицу клиентов и оттуда брать некий id. Постараться протащить id клиента во все таблицы связанный с ним таблицы. Когда у вас вырастет количество клиентов, вы сможете его использовать как часть ключа для шардинга. А если попадется очень-очень жирный клиент, его можно будет легко и без последствий выдернуть на отдельную машинку.

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

Я так понимаю, никаких здоровых процессов по развертывания проекта у вас нет. Советую присмотреться к какой-нибудь CI, даже тот же Deployer облегчит вашу жизнь. Он прекрасно работает в связке с Laravel.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы