我所理解的并发有两种:
- 一个玩家不断的点击登录(或其他按钮)向服务器断发送请求:
- 很多个玩家同时点击该程序时发送大量请求:
对于上述情况我们怎么处理呢?
问题一
有的玩家是不小心点击了两次,有的是故意多次点击无论是处于那种情况我们都应该正确处理:
- 可以在前台页面通过js控制按钮为不可用,达到前台控制的目的代码如下: $('#id').attr('disabled',true);
- 发送请求后,无论验证是否成功,一定要将服务器顿存的验证码的SESSION清除掉
- 用memcache或是SESSION做个标记来控制玩家发送请求数。
到目前为止关于这种并发的处理,只想到了这种方法。
问题二
我们在发奖品时,尤其是涉及到贵重奖品一般会采取踩楼的形式。这样就要求我们必须严格的计算出用户的楼层,所以一般都是采用队列的形式。而队列的使用一般又分为两种情况
- 将奖品完全存放到队列中,当玩家参与活动时就从队列中拿出一个奖品发放给玩家。
- 队列只是作为一个强制排队的工具,当玩家进来时全部的放入队列中,通过后台断脚本不断从队列中获取数据并进行处理。
另外,有时候人数过多会出现同一个激活码发给两个玩家,这种情况我们创建一个自增的表,每次以增表的id作条件去获取激活码(具体流程可参照“活动开发规范与流程“);
但就个人而言为了能够使程序更安全的执行下去,我们完全可以将上述几种解决方案整合到一起也是目前我经常使用的:
- 在前台通过js控制,当按钮点击后设置为不可使用。活动上线后将js在线进行压缩。
- 在后台用户每次登陆无论成功与否都要将验证码的SESSION清空。
- 以缓存或SESSION作为一个标记(下面以Tt为例)。
- 当从队列中取出数据时将该标记删除;
- 表以自增的方式创建
以SESSION或Tt标记的代码如下:
$mark = 'passport'; $status =$Ttserver->get($mark); if(empty($status)){ echo ”说明没有在队列中,需要将该数据放入队列”; }else{ echo "正在排队......"; }
数据出队列时将其删除代码如下:
function deletemark($mark){ global $Ttserver; $rs = $Ttserver->delete($mark); if($rs){ return $rs; }else{ return 'fail'; } }