2011-06-03 133 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