php redis auth 高并发,PHP+Redis高并发

初学Redis,于是便想写一个高并发的项目,最开始只能达到并发量1,后来增加并发,出现各种问题,我又采取各种办法来增大并发量,在慢慢增大并发量的过程中,我也在慢慢成长,在追求成功的过程中,越来越兴奋,成长的感觉,也是人生中最美妙的事情!

需求:一个抢课系统,使用Redis,course_1为课程的人数,user_1为哪些用户选择了课程,采用数组形式,由于ab压测,我不知道怎么传动态参数,于是我变用的随机数代替。

首先先来看代码:

$redis = my_redis();

if($redis->get('course_1') <= 0){

$this->apiReturn(303,'课程已被抢完');

}

$redis->decr('course_1');

$data = $redis->get('user_1');//获取key [value]

$data = json_decode($data,JSON_UNESCAPED_UNICODE);

array_push($data,mt_rand(1,100));

$data = json_encode($data);

$redis->getset('user_1',$data);

1fb471f80317

抢课人数结构

1fb471f80317

课程人数结构

第一次测试,总请求量100,同时并发量为1,课程人数100:

ab -n1000 -c50 http://127.0.0.1/lession_admin/public/index.php/api/test

-n一共多少次请求,-c瞬间的并发数

注意,localhost要改成127.0.0.1,不然会被积极拒绝(到底有多积极???)。

ab -n100 -c1 http://127.0.0.1/lession_admin/public/index.php/api/test

结果:课程数为0(正常)

[94,76,85,79,87...].length = 100(正常)

第二次测试,总请求量100,同时并发量为5,课程人数100:

结果:课程数为0(正常)

[94,76,85,79,87,32,64...].length = 95(异常)

我们发现少了5个人,那么会不会跟总请求量有关,于是我们改一下请求量

第三次测试,总请求量300,同时并发量为5,课程人数100:

结果:课程数为0(正常)

[94,76,85,79,87,32,64...].length = 89(异常)

很惊讶,每秒钟同时5的并发量,功能就已经产生异常了,这就得考虑代码问题了。

我们看到,每秒钟5个人访问,就出了问题,那么肯定是代码问题,我们看到,每次-1,这种思路不可取,非常容易出问题,于是我换一种思路,判断已经选课的人数,有没有超过总人数,如果超过了,就不能再选课,实验后发现,我这种做法是正确的,并且取得了很好的效果,Redis里的字符串(我刚开始因为看到可以自减,所以选择字符串结构,现在发现自己是错的),也改为了set结构,因为它有去重的功能:

$courseId = 1;

$id = I('id');

$id = (int)$id;

$redis = my_redis();

这里的if是重点,判断人数100,有没有小于抢的人数,如果小于,那么就返回失败,这里是精华,之前自减1,真的太多漏洞了。

if($redis->smembers('course_' . $courseId)[1] <= count($redis->smembers('user_' . $courseId))){

$this->apiReturn(303,'课程已被抢完',["num"=>count($redis->smembers('user_1'))]);

}

$result = $redis->sismember('user_' . $courseId, $id);

if ($result) {

$this->apiReturn(304,'您不能重复抢课');

}

$result_Add = $redis->sadd('user_' . $courseId, $id);

if ($result_Add) {

$this->apiReturn(200,'抢课成功');

}

$this->apiReturn(305,'抢课失败');

1fb471f80317

课程信息

1fb471f80317

线程,一秒请求十万

1fb471f80317

随机变量1-500

1fb471f80317

http请求带参数

1fb471f80317

采用set结构,可以去重,在这个业务场景下,比list好用

第四次测试得出:

10000并发数据正常,也是100条数据,并没重复。

50000并发数据异常,超出3条数据,并没重复。

100000并发数据异常,超出1条数据,并没重复。

从并发量5异常,到并发量一万正常,就几行代码解决了这个问题,代码真的是很奇妙的东西。

搭建分布式:

redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385

检测

redis-trib.rb check 127.0.0.1:6379

如果说第二次启动报错的话,

错误信息为:

[ERR] Node 127.0.0.1:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

下面我开始用分布式锁,来解决并发的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值