2013-06-18 33 views
0

我們正在開發這是應該由10000人在同一時間登錄到至少訪問的Web應用程序。現在,我們正在努力解決以下問題,併發登錄使用PHP

目的 - 禁止併發登錄(以相同的憑據登錄)

走近解決方案 - AJAX調用上一個javascript定時器運行檢查當地的會話ID和會話ID在D B。詳細解釋請參考avoid concurrent login

問題 - 由於網上人數衆多,每10秒鐘通過計時器擊中服務器,正在以最大連接數/秒和不必要的客戶端 - 服務器事務的方式爲服務器創建巨大的負載即使沒有併發登錄。

解決方案 - 難道還有比我們目前的做法等任何其他方式來解決併發登錄的問題。

很多感謝您的輝煌!!! ...

+1

我們在一項工作中處理這個問題的方式是創建一個「會話」表,以保持當前登錄的用戶。這張表加載了諸如「登錄時間」,「ip/mac addy」,「用戶名」,「瀏覽器」等信息......基本上是關於用戶的「會話」信息。所以當登錄時,它檢查了這張表是否已經被記錄,如果是的話,並且如果新登錄的憑證被滿足,那麼我們從會話表中刪除舊的行並添加新的。在後端是一個每分鐘運行一次的cron作業,用於檢查重複的條目,並首先刪除最老的條目。 – SpYk3HH

+0

更好的方法是將會話數據存儲在redis中,並在有人再次登錄時刪除會話。這將自動從前一個會話中註銷用戶 – Amit

回答

0

有趣的問題。

我會說,什麼可以做,使用純基於RAM的解決方案很可能是這種類型的問題最合適的。 Mysql有一個基於RAM的存儲引擎,但除此之外,memcached和redis都具有自動數據到期並可能具有優越的性能,所以我認爲它們更合適。請參閱Redis expirememcached expiration

如果你能確保你只在RAM打到的東西,我相信你已經贏了一半了。

除此之外,儘量仔細評估你真的是多麼經常需要從客戶端執行「Ping」。如果用戶空閒,是否需要客戶端每10秒發送一次ping?是否有可能在會話過期後處理用戶交互? (比如讓用戶點擊一個按鈕,然後系統按照「您已經登錄,請關閉另一個窗口」的方式響應某些內容。如果用戶沒有花費很長時間寫入表單,才發現他們已經退出,一旦他們提交。)

什麼是最糟糕的情況?

嘗試這樣的場景:

| time | Client 1 | Client 2 | Server      | 
| t0 | Log in  |   |       | 
| t1 |    |   | Authorize client 1 session | 
| t2 | Send ping |   |       | 
| t3 |    |   | Update client 1 session | 
| t4 |    | Log in |       | 

讓我們說,T3和T4之間的時間間隔爲1秒。在這種情況下,接下來發生的事情是:

| t5 |    |   | Server rejects client 2 | 

如果T3和T4之間的時間是20秒,ping時間間隔爲10秒,我們假設客戶端1已逝,:

| t5 |    |   | Delete client 1 session | 
| t6 |    |   | Authorize client 2 session | 

但是,您可以使用ping時間間隔更長的模型,並在客戶端登錄之前引入可能的延遲。鑑於平時間爲60秒,T3和T4之間的時間是30秒:

| t4+30| Send ping |   |       | 
| t5 |    |   | Server rejects client 2 | 

或者 - 如果客戶端1不在了,

| t4+30|    |   | Delete client 1 session | 
| t6 |    |   | Authorize client 2 session | 

但這種延遲纔會發生,如果有已經是來自另一個客戶的最近登錄,所以如果典型用例每個用戶只有一個客戶,那麼它不會造成嚴重問題。