Пользовательские сеансы Django с отключенной привязкой AWS Load Balancer

Я использую AWS Elastic Beanstalk с серверами EC2 за Elastic Load Balancer (ELB).

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

Что я хотел бы сделать, так это использовать пользовательские сеансы на стороне сервера, где информация об аутентификации пользователя хранится в моем кеше Redis. Я пытался установить SESSION_ENGINE для множества вещей, таких как:

SESSION_ENGINE = 'redis_sessions.session' 
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

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

Вот некоторые другие соответствующие настройки, которые у меня есть:

INSTALLED_APPS = (
    ...,
    'django.contrib.sessions',
    ...,
)
MIDDLEWARE_CLASSES = (  
    ...,
    'djangosecure.middleware.SecurityMiddleware',
    ...,
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...,
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    ...,
)

Что я делаю не так? Большое спасибо.


person Victor J Wang    schedule 19.04.2016    source источник
comment
У меня похожая проблема на AWS ECS. Если у меня есть несколько контейнеров докеров, работающих на одном экземпляре, меня часто перенаправляют для входа в систему в зависимости от того, какой контейнер его подбирает. Я использую многопортовое сопоставление, чтобы получить максимальную отдачу от своего экземпляра, но, похоже, прерываю сеансы в django.   -  person radtek    schedule 18.08.2018


Ответы (2)


Вы уверены, что все ваши веб-серверы на самом деле подключаются к одному и тому же общему экземпляру Redis, например: в сети, такой как AWS ElastiCache (и не по умолчанию что-то на своих локальных хостах)?

Если вы используете SESSION_ENGINE = 'django.contrib.sessions.backends.cache', убедитесь, что кеш, который он использует, установлен на кеш Redis, который вы настроили в CACHES, возможно, с SESSION_CACHE_ALIAS, если не default.

person Bartvds    schedule 10.11.2017

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

Решение здесь заключается в использовании другого механизма хранения сеансов, который может быть разделен между несколькими серверами. Одним из примеров может быть использование Redis в качестве хранилища сеансов. Затем оба сервера могут подключаться к одному и тому же экземпляру Redis и иметь одинаковое состояние сеанса.

Ссылка объясняет, как этого можно добиться - http://michal.karzynski.pl/blog/2013/07/14/using-redis-as-django-session-store-and-cache-backend/

person Shivam Vijaywargiya    schedule 03.12.2019