有趣的问题。
我会说,什么可以做,使用纯基于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