2013-06-18 34 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 | 

但这种延迟才会发生,如果有已经是来自另一个客户的最近登录,所以如果典型用例每个用户只有一个客户,那么它不会造成严重问题。