关闭了AWS Load Balancer粘性的Django用户会话

时间:2016-04-19 17:09:47

标签: django load-balancing elastic-beanstalk django-sessions sticky-session

我在Elastic Load Balancer(ELB)后面使用AWS Elastic Beanstalk和EC2服务器。

我在ELB上启用了“粘性会话”,因为这是我可以让django用户会话正常工作的唯一方法。但是,在高峰流量时,这会导致问题,因为ELB不再均匀地分配每个传入请求。这通常会像迷你DDOS一样超载1台服务器。

我想要做的是使用服务器端用户会话,其中用户身份验证信息存储在我的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',
    ...,
)

我做错了什么?非常感谢。

2 个答案:

答案 0 :(得分:0)

您确定所有的Web服务器实际上都连接到同一个共享redis实例,例如:在网络上如AWS ElastiCache(并且不会默认为其本地主机上的某些内容)?

如果您使用SESSION_ENGINE = 'django.contrib.sessions.backends.cache',请确保将其使用的缓存设置为您在CACHES中配置的redis缓存,如果不是SESSION_CACHE_ALIAS,可以使用default

答案 1 :(得分:0)

如果要跨多个服务器实现django应用程序的负载平衡实现,则不能直接使用默认会话身份验证方法,因为它使用内存作为会话存储。在这种情况下,当您登录实例之一时,此状态存储在该特定服务器的内存中。如果您的下一个请求发送到其他服务器,则将显示为未经身份验证。

这里的解决方案是使用不同的会话存储机制,该机制可以在多个服务器之间共享。一个示例是将redis用作会话存储。然后,两个服务器都可以连接到相同的Redis实例,并具有相同的会话状态。

链接说明了如何实现- http://michal.karzynski.pl/blog/2013/07/14/using-redis-as-django-session-store-and-cache-backend/