一、利用incr实现原子性的递增

例如需求:一个手机号一分钟只能发送一次短信验证码。

  1. $number = $client->incr('number');
  2. if ($number == 1) {
  3. //发送验证码
  4. } else {
  5. //limit 1次/1分钟
  6. }

二、利用redis锁、监听、事务等

例如需求:10:00准时开放抢购,限前100人。

  1. $expireTime = 500000; //锁过期时间50ms
  2. $key = 'lock';
  3. $microtime = 0;
  4. //循环设置锁,如果锁已经存在则继续循环
  5. while (1) {
  6. $microtime = microtime(true) * 1000 * 1000 + $expireTime;
  7. $setn = $client->setnx($key, $microtime);
  8. if ($setn) {
  9. break;
  10. }
  11. //监听锁
  12. $client->watch($key);
  13. //获取别人锁设置的时间
  14. $expire = $client->get($key);
  15. //当前时间早就超过了别人锁的时间
  16. if ($expire && $expire < microtime(true) * 1000 * 1000) {
  17. //开启事务
  18. $client->multi();
  19. //这锁归我用了(更新锁的时间,并返回锁的旧时间赋值给变量)
  20. $oldExpire = $client->getset($key, microtime(true) * 1000 * 1000 + $expireTime);
  21. if ($client->exec() && $oldExpire && $oldExpire < microtime(true) * 1000 * 1000) {
  22. //锁归我成功,推出找锁循环
  23. break;
  24. }
  25. } else {
  26. //取消监听锁
  27. $client->unwatch();
  28. }
  29. //一次循环结束,
  30. usleep(3000);
  31. }
  32. //进入到此,说明锁在这个人手上
  33. $number = $client->get('number');
  34. if ($number >= 100) {
  35. $client->del($key);
  36. //醒醒,都抢光了
  37. }
  38. //其他操作
  39. usleep(rand(50000, 100000));
  40. //我抢到了,人数+1
  41. $number = $client->incr('number');
  42. //释放锁【锁还是自己的才需要实放】
  43. if ($client->get($key) == $microtime) {
  44. $client->del($key);
  45. }

src=http___blog.wuhequan.cn_upload_portal_20190801_8ab95379a7a6d6a0c5fe5527204842be.png&refer=http___blog.wuhequan.jpg

前提是:redis服务器别挂!!!