2011-06-03 129 views
1

最近,我开始在我的基于Django的网站上遇到问题,登录将失败,并在网站正常运行几天后向用户报告错误。已登录会话继续正常工作,但不会发生新的登录。Django登录尝试有时会默默失败

相关信息:

  • 我使用的是正常django.contrib.auth认证的东西

  • 我通过django.db.backends.postgresql_psycopg2后端

  • 我OSX上运行使用PostgreSQL为DB 10.6.7与Python 2.6.1和Django 1.3

  • Django is在FastCGI的模式下运行背后nginx的

我的直觉是,有一次是什么打破在连接/插座到DB在某些时候,因为如果我杀了Django和重新启动,一切工作就好了(即数据库本身绝对不会超载,使用psql命令行工具可以很好地访问)。

不幸的是,在日志中没有任何关于错误的信息(好吧,至少没有任何东西是通过普通Python logging模块发出的,这就是我如何捕获所有日志)并且没有错误报告给Web浏览器。所有的客户端都会看到他们被重新发回到登录页面,就好像他们刚刚刷新了浏览器一样。

任何帮助非常感谢。

不知道,如果是相关的,但我的中间件类:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.transaction.TransactionMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
) 

UPDATE

寻找到nginx的访问日志后,我可以看到,登录实际工作简要地后,突然没有按't work:

"POST /accounts/login/ HTTP/1.1" 302 5 "https://myapp.com/accounts/login/?next=/orders" 
"GET /orders HTTP/1.1" 301 185 "-" 
"GET /orders HTTP/1.1" 302 5 "-" 
"GET /accounts/login/?next=/orders HTTP/1.1" 301 185 "-" 
"GET /accounts/login/?next=/orders HTTP/1.1" 200 1297 "-" 

正如您所看到的,登录工作并将客户端重定向到“下一个”URL(/ ord然后第三行将客户端重定向(302)返回到登录页面,这可能是因为@login_required装饰器(应用于/ orders控制器)确定它们并未真正登录。

为了进行比较,这是一个成功登录序列:

"POST /accounts/login/ HTTP/1.1" 302 5 "https://myapp.com/accounts/login/?next=/orders" 
"GET /orders HTTP/1.1" 301 185 "-" 
"GET /orders HTTP/1.1" 200 59364 "-" 

并与错误的密码的登录(在POST回来与200,而不是302):

"POST /accounts/login/ HTTP/1.1" 200 1426 "https://myapp.com/accounts/login/?next=/orders" 

一个之间的差正常的登录和破损的是客户得到一个200 OK /订单而不是302返回到登录页面。我不知道auth中间件如何允许登录,然后立即将用户踢出去。是否有可能的竞争条件,登录控制器无法及时将登录状态持久保存到数据库中,以便/ orders控制器查看并允许用户保持登录状态?

另外 - 我注意到,Django重新启动不一定需要解决这个问题 - 有时服务器只是奇迹般地开始让客户再次登录。

+0

您使用的是什么Web服务器?你检查了Web服务器的日志吗? – 2011-06-03 14:35:12

+0

我在FastCGI模式下运行Django,nginx坐在它前面。由于现有会话仍然有效,并且位于同一个nginx实例后面的其他webapps允许登录,同时该网站无法登录,所以我认为它与位于现场。 – glenc 2011-06-03 15:50:06

+0

那么,杀死Django并重新启动它可以解决问题的事实似乎表明了另一种情况。如果您认为这是数据库问题,那么您必须重新启动或以其他方式混淆数据库才能使其再次正常工作。检查Web服务器的日志,并在将来尝试分解解决方案,以便将其缩小更多。例如,如果您正在运行memcached,请尝试重新启动并保留其他所有内容。您也可能想尝试重新启动数据库,以便在重新引导整个服务器之前查看是否足以解决问题。 – 2011-06-03 17:17:18

回答

1

听起来像您的Web服务器使用持久连接并用完。当您无法登录时,pg日志会说什么?

+0

Hi scott - 谢谢你的提示,你说的对,Django把连接限制给了postgresql,但是由于某种原因,在日志中没有显示连接错误,我花了几个小时看着pgpool-II并且设置它,现在问题已经消失,感谢上帝! – glenc 2011-06-04 19:15:33