有趣的問題。
我會說,什麼可以做,使用純基於RAM的解決方案很可能是這種類型的問題最合適的。 Mysql有一個基於RAM的存儲引擎,但除此之外,memcached和redis都具有自動數據到期並可能具有優越的性能,所以我認爲它們更合適。請參閱Redis expire和memcached 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 |
但這種延遲纔會發生,如果有已經是來自另一個客戶的最近登錄,所以如果典型用例每個用戶只有一個客戶,那麼它不會造成嚴重問題。
我們在一項工作中處理這個問題的方式是創建一個「會話」表,以保持當前登錄的用戶。這張表加載了諸如「登錄時間」,「ip/mac addy」,「用戶名」,「瀏覽器」等信息......基本上是關於用戶的「會話」信息。所以當登錄時,它檢查了這張表是否已經被記錄,如果是的話,並且如果新登錄的憑證被滿足,那麼我們從會話表中刪除舊的行並添加新的。在後端是一個每分鐘運行一次的cron作業,用於檢查重複的條目,並首先刪除最老的條目。 – SpYk3HH
更好的方法是將會話數據存儲在redis中,並在有人再次登錄時刪除會話。這將自動從前一個會話中註銷用戶 – Amit