Поддержка нескольких арендаторов в Java EE 6 - PullRequest
15 голосов
/ 25 июня 2011

У меня есть приложение Java EE 6 (развернуто в Glassfish v 3.1), и я хочу поддерживать несколько арендаторов.Технологии / API, которые я сейчас использую в своем приложении:

  • EJB (включая службу таймера EJB)
  • JPA 2.0 (EclipseLink)
  • JSF 2.0
  • JMS
  • JAX-RS
  • Я также планирую использовать CDI

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

Будет много клиентов, поэтому все данные будут находиться в одной схеме БД.

Ответы [ 4 ]

4 голосов
/ 05 июля 2011

Persistence Layer

Начните с персистентного слоя.Прокрутите вверх по вашей архитектуре, как только вы это сделаете.

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

Сложность заключается в том, что это очень ручной процесс.

Если вы используете Hibernateкак ваш поставщик JPA, есть некоторые инструменты, которые помогут с этим;а именно Фильтры гибернации .

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

Я не использовалEclipseLink, но, похоже, также имеет хорошую поддержку Multi-Tenancy .DiscriminatorColumn выглядит очень похоже на концепцию Hibernate Filters.

Сервисный уровень

Я предполагаю, что вы используете JAX-RS и JMS для сервисного уровня.Если это так, то вам также нужно подумать о том, как вы собираетесь передать tenantId и аутентифицировать ваших Арендаторов.Как вы собираетесь предотвратить доступ одного арендатора к услуге REST другого?То же самое для JMS.

Уровень пользовательского интерфейса

Вам нужно будет подключить свой логин в вашем пользовательском интерфейсе к Bean (Hibernate или Eclipselink), который устанавливает TenantId для фильтра / дискриминатора.

0 голосов
/ 28 июня 2011

Есть несколько способов, которыми вы можете воспользоваться этим, в зависимости от уровня разделения, которого вы хотите достичь, и количества одновременно работающих арендаторов, которых вы хотите поддерживать. С одной стороны, вы можете создать новую схему для каждого арендатора и, следовательно, обеспечить изоляцию данных на уровне базы данных. Для большинства практических целей обычно достаточно логического разделения ваших данных, назначая tenant_id каждому объекту в вашей доменной модели и поддерживая ограничения внешнего ключа. Конечно, это означает, что вы, вероятно, захотите всегда передавать текущую сессию tenant_id каждому методу запроса / поиска, чтобы он мог ограничить набор данных, основанный на этом. Вы должны убедиться, что пользователи не могут получить доступ к данным другого арендатора, введя идентификатор арендатора (или идентификатор объекта), который не принадлежит им в URL.

0 голосов
/ 03 июля 2011

Go, ориентированная на сообщения.

Если вы выбираете обмен сообщениями в качестве стратегического подхода и реорганизуете (при необходимости) бизнес-логику вокруг JMS, тогда другие варианты остаются жизнеспособными и применимыми на местном уровне.

При таком подходе вы платите определенную фиксированную стоимость (рефакторинг) в существующей системе (с одним арендатором). Затем вы можете применять подходы различной степени сложности, начиная от простого разбиения (связывание на основе идентификатора @ Geziefer) до полномасштабного подхода shared-core-schema + extended-tenant-специфичные схемы, не влияя на архитектуру системы и дополнительный рефакторинг.

В дальнейшем вы будете иметь ортогональный контроль над потоками данных вашей системы через уровень обмена сообщениями (применение маршрутизаторов, фильтров, специальных путей обработки и т. Д.)

[редактировать по запросу]

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

0 голосов
/ 28 июня 2011

Расскажите нам о количестве и степени разделения и настройки, необходимых для различных арендаторов.

Если у вас небольшое количество арендаторов, я бы предложил создать настраиваемый продукт "white label". Это дает вам возможность создать некоторые конкретные вещи для одного арендатора, не усложняя вопросы. Кроме того, разделение приложений на арендатора помогает вам в обслуживании. Мы сделали это для продукта с несколькими разными арендаторами.

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

...