Как соединить два проекта django на двух разных серверах

Проблема: У меня есть сайт, который имеет различные приложения (Accounts, Community, Company, Payments, Main_project_app).

Я хочу создать подобную архитектуру типа google, где база пользователей находится на одном сервере, а другие приложения, такие как Gmail, drive и т.д., предоставляют определенные услуги на разных серверах на основе аутентификации пользователя с главного сервера базы пользователей Google, то есть. Приложение Accounts, которое содержит информацию о пользователе, такую как имя пользователя, email, пароль и т.д., должно оставаться на одном сервере, а с помощью REST API или чего-то подобного мы соединяем приложение Accounts с другим сервером, чтобы перевести пользователя со страницы регистрации на приборную панель и предоставить ему другие услуги, используя все остальные приложения.


Я новичок, поэтому, пожалуйста, если я допустил какие-то ошибки в объяснении или что-то еще, поправьте меня.


TLDR: django не может выполнять поиск внешних ключей между базами данных, что трудно решить новичку, поэтому django может быть неправильным инструментом, или подход разделения базы данных должен быть опущен.

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

Но я могу попытаться дать вам общий обзор и первую проблему, с которой вы, скорее всего, столкнетесь.

где база пользователей находится на одном сервере, а другие приложения, такие как Gmail, drive и т.д., обслуживают конкретные услуги на разных серверах

Хорошо, насколько я понимаю, вы хотите разделить вашу базу данных по типу модели. В частности, вы хотите, чтобы модель User находилась на другом сервере баз данных с другим экземпляром django, выполняющим аутентификацию. В принципе, это можно сделать, разделив базу данных локально.

Назовем сервер с базой данных User сервером AuthServer, а другой сервер AppServer. AuthServer должен обслуживать API, который получает учетные данные пользователя и решает, может ли пользователь войти в систему или нет. Тем временем AppServer должен локально кэшировать экземпляры User, чтобы не переаутентифицировать пользователя при каждом запросе. Это легко сделать, реализовав пользовательский AuthenticationBackend. Теперь AppServer получает запрос на вход, может передать его AuthServer и получить экземпляр пользователя при успехе или не получить при неудаче входа.

Это хорошо работает даже с отношениями между User и другими моделями приложений, потому что AuthServer и AppServer могут использовать один и тот же сервер базы данных. Но это как-то противоречит цели их разделения, как вы хотите сделать это в первую очередь. Поэтому django предлагает подход иметь несколько баз данных (в документации даже используется именно этот пример, из которого я скопирую код). В вашем файле настроек вы можете хранить несколько соединений с базами данных.

DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'postgres_user',
        'PASSWORD': 's3krit'
    },
    'users': {
        'NAME': 'user_data',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'priv4te'
    }
}

Далее вы можете написать DatabaseRouter, который, вероятно, будет выглядеть примерно так (неполный пример):

class AuthRouter:
    route_app_labels = {'auth', 'contenttypes'}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'users'
        return 'default'

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'users'
        return 'default'

Для полноты картины необходимо добавить маршрутизатор в настройки

DATABASE_ROUTERS = ['path.to.AuthRouter', ]

Теперь первая проблема, с которой вы столкнетесь, если вы захотите связать модель User с какой-либо другой моделью, что крайне вероятно. Django не позволяет иметь перекрестные связи с базами данных в плане внешних ключей к моделям в других базах данных. Вы можете обойти эту проблему очень сложным способом, используя IntegerField вместо полей ForeignKey и самостоятельно позаботиться об интегрированности баз данных, но я не рекомендую вам этого делать.

В конце концов, django не является подходящим инструментом для создания таких широко распространенных сервисов, если вы находитесь на уровне новичка, как вы говорите, или вы должны подготовиться к очень сложному и подверженному ошибкам опыту :)

Вернуться на верх