Как вы управляете расширяемостью в своих мультитенантных системах?

13

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

Дополнительное поле здесь или там, может быть, дополнительная страница или какая-то дополнительная логика в середине рабочего процесса - такие вещи.

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

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

Так что люди делают, чтобы справиться с этим? Force.com, кажется, мастер расширяемости; очевидно, они создали платформу с нуля, которая является супер расширяемой. Вы можете добавить практически все что угодно с помощью веб-интерфейса. FogBugz сделал нечто похожее на то, что они создали надежную модель плагина, которая, если подумать, на самом деле могла быть вдохновлена ​​Force. Я знаю, что они потратили на это много времени и денег, и если я не ошибаюсь, намерение было на самом деле использовать его для дальнейшей разработки продукта.

Звучит так, как будто я мог соблазниться, но, вероятно, не должен. :)

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

РЕДАКТИРОВАТЬ: Похоже, что FogBugz справился с проблемой, построив довольно надежную платформу, а затем использовать его, чтобы собрать свои экраны. Чтобы расширить его, вы создаете DLL, содержащую классы, которые реализуют интерфейсы, такие как ISearchScreenGridColumn, и это становится модулем. Я уверен, что его сборка была чрезвычайно дорогой, учитывая, что у них есть большое количество разработчиков, и они работали над этим месяцами, плюс их площадь поверхности составляет, возможно, 5% от размера моего приложения.

Сейчас я серьезно задаюсь вопросом, является ли Force.com правильным способом справиться с этим. И я - опытный парень из ASP.Net, так что это странная позиция, в которой я могу оказаться.

Брайан Маккей
источник
3
Я предполагаю, что это - ТАК вопрос, который делает этот идентичный перекрестный пост. Не делайте этого, либо задайте вопрос SO для переноса сюда, либо, если вы ищете разные ответы, скажите нам точно, почему ответы на вопрос SO не удовлетворяют.
Яннис
Вы правы, вопрос к программистам лучше, но кажется, что вы получили довольно приличные ответы. Я отредактировал вопрос для ссылки на вопрос SO.
maple_shaft

Ответы:

8

Я столкнулся с подобной проблемой, и я расскажу вам, как я решил ее.

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

  2. Каждая часть системы содержится в модуле. Модуль имеет зависимости (другие модули, от которых он зависит). Например, «базовая» система имеет безопасность (пользователи, группы, роли, политики паролей), локаль, (переводы, страны, культуры), хранилище файлов, электронную почту и т. Д. И т. Д. Каждый модуль определяет себя с помощью файла XML. Файл xml в основном определяет схемы, таблицы, классы вычислений, определения экранов и так далее. Они считываются при запуске приложения, если дата файла изменилась .

  3. Клиентские модули имеют свои собственные XML-файлы и собственную DLL. Это все плюс и функционирует соответственно и прозрачно с остальной частью системы. Прямо до замены существующих представлений MVC пользовательскими, с пользовательским кодом и пользовательскими моделями представления.

  4. Если клиент желает расширить существующую функциональность, xml / system предоставляет метод, с помощью которого я могу «извлечь» один модуль из другого. Новый модуль обладает всеми существующими функциями, но с учетом специфических требований заказчика в новой DLL и с расширенным XML-файлом, который может вносить изменения. Предостережение заключается в том, что они не могут фактически удалить существующие поля в этой системе, но мы можем расширить его и предоставить совершенно новые объекты и функциональные возможности.

Moo-Сок
источник
+1: Похоже, это заняло час или два. :)
Брайан Маккей
1
@BrianMacKay, хорошо, как только работа была сделана (и это было утомительно), наши клиенты были очень очень довольны скоростью, с которой мы могли изменить настройки. Обратите внимание, что инфраструктура MVC (насколько это касается просмотров / страниц) не очень хорошо подходит для нескольких проектов. Мы обошли это, используя свойства свойств SVN и загрузив основные виды из основного репозитория, и использовали CSS / макеты для его настройки. Но год, добрые несколько часов: P
Moo-Juice
Просто интересно, как вы думаете, сколько времени потребовалось для реализации самой архитектуры и сколько разработчиков было вовлечено?
Брайан Маккей
1
@BrianMacKay, это было 5 месяцев. Один разработчик пользовательского интерфейса для всех видов CSS / HTML / Partial, javascript и т. Д., И один внутренний разработчик (я) для всего остального.
Му-сок
4

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

Я советую по-другому. Я советую держать вещи простыми над сложными.

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

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

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

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

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

Джейсон Себринг
источник
+1 за обмен опытом. Многое из того, что я слышу, это «это очень сложная проблема». Реальность, с которой я имею дело, состоит в том, что эта система будет иметь множество настроек, и они не все подходят для всех ... Звучит так, будто вы говорите, что использовали подход, раскрывающий уровень обслуживания, а затем позволяющий людям потреблять это. однако они хотят - у меня есть преимущество, по крайней мере, в том, что мы пишем все расширения внутренне. Но это все еще беспорядок, чтобы управлять (cntd)
Брайан Маккей
Я пришел к выводу, что вам придется написать платформу, которая поддерживает собственное представление о компонентах пользовательского интерфейса и динамической композиции, а затем построить все приложение, используя эту платформу. И поэтому я начинаю думать, что было бы разумно просто написать все это в force.com, потому что это то, что такое force.com!
Брайан Маккей
Брайан, FYI kitgui.com и hubsoft.com, если вам интересно.
Джейсон Себринг
2

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

Это простой и эффективный способ хранения дополнительных данных для пользователя. Дополнительная информация должна храниться об именах и типах этих полей.

Это охватывает пользовательские поля для клиента. Для пользовательского поведения API веб-сервисов допускает расширения.

spirc
источник
1

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

2) Да, модульность и настраиваемость жестки. Могут помочь такие вещи, как шаблон «Стратегия» (причудливое имя для указателей на функции; в Java это обычно реализуется путем объявления интерфейса, который пользователи класса могут реализовать для настройки поведения вашего кода), но вы захотите быть очень изолированными и отделенными код для этого, чтобы работать.

3) С точки зрения данных, это может быть одним из примеров полезного хранения без схемы. Если у вас есть реляционная модель данных, наличие таблиц с большим количеством столбцов для разных клиентов проблематично (да, в конечном итоге вы получите множество столбцов, которые можно обнулять, что плохо ; одна из причин заключается в том, что трудно или невозможно установить правильные ограничения [т.е. ограничения, не допускающие появления недопустимых комбинаций нулей]). Добавление клиента специальных таблиц (то есть usersи foo_usersс usersпроведением поля , действительным для всех клиентов и foo_usersимеющим специфический fileds Foo) лучше; Вы можете легко иметь правильные ограничения, но ваша СУБД может не справиться с этим корректно (из-за разрыва соединения, ограничений на количество таблиц и т. д.) и, вероятно, будет выглядеть уродливо в вашем коде.

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

Алекс
источник