Я работаю над будущим мультитенантным веб-приложением, которое должно будет поддерживать тысячи пользователей. Приложение создается на основе Play! MVC Framework с использованием JPA / Hibernate и postgreSQL.
Я смотрел доклад Гая Наора на тему Написание мультитенантных приложений в Rails , в котором он рассказывает о нескольких подходах к мультитенантности (изоляция данных уменьшается по мере продвижения по списку):
Я остановился на подходе №2, в котором идентификатор пользователя извлекается из запроса и затем используется для доступа к этому табличному пространству пользователей. Команда postgres SET search_path TO customer_schema, public
дается перед выполнением любого запроса, чтобы убедиться, что таблицы клиента являются целью запроса. Это легко сделать с помощью аннотаций контроллера @Before
в методах контроллера в Play! (это подход, который Гай использовал в своем примере с рельсами). search_path в postgres действует точно так же, как $ PATH
в ОС; классно!
Все это звучало великолепно, но я сразу же столкнулся с трудностями при реализации этого поверх стека JDBC / Hibernate / JPA, потому что, похоже, нет способа динамически переключать схемы во время выполнения.
Кажется, что соединения с базой данных статически настраиваются фабрикой соединений (см .: Как управлять множеством схем в одной базе данных с использованием спящего режима ). Я нашел похожие вопросы с похожими ответами на использование нескольких SessionFactorys для каждого пользователя, но поскольку я понимаю, что SessionFactorys являются объектами с большим весом, маловероятно, что вы могли бы поддерживать сотни пользователей, не говоря уже о тысячах пользователей, идущих по этому пути.
Я не полностью посвятил себя подходу №2, описанному выше, но я еще не совсем отказался от него для подхода №3.