PHP怎样基于redis的散布式锁防止高并发反复要求
需求:
我们先举个某系统验证的列子:(A渠道系统,业务B系统,外部厂商C系统)
(1)B业务系统调取A渠道系统,验证传入的手机、身份证、姓名三要素可否一致。
(2)A渠道系统再调取外部厂商C系统。
(3)A渠道系统将结果返回给B业务系统。
这3个历程中,(2)历程,调取外部厂商是需要计费的。
当B业务系统并发量很高时,有100笔雷同的三要素校验,由于是雷同的三要素,A渠道只要调取一次厂商即可知道结果。为了防止在某一恳求还没响应完毕的同时,其他恳求也去调取外部系统,这个时候就需要加锁处置
分布式锁的特点
● 原子性:统一时刻,只能有一个机器的一个线程得到锁;
● 可重入性:统一对象(如线程、类)可以反复、递归调取该锁而不发生死锁;
● 可堵塞:在没有获得锁此前,只能堵塞等候直至获得锁;
● 高可用:哪怕发生程序故障、机器破坏,锁依然能够得到被猎取、被开释;
● 高机能:猎取、开释锁的操纵耗损小。
要实现:加锁,减锁,锁超时
实现方式可以是:数据库 mc redis 系统文件 zookeeper
我此刻就是渠道系统,当100个雷同的业务恳求传递过来,我的第一个恳求要先加锁,然后恳求外部厂商系统,等响应结果今后,插入另一个key中,然后再删除锁。
其他恳求先去猎取下锁,假如已经存在锁就轮寻等候,假如锁不在了,直接去查询结果。
假如第一个恳求失败了,结果并没有插入到位,就连续猎取锁再去查询外部系统。
猎取锁:
$redis->set('lock:手机号&身份证&姓名', 1, ['nx', 'ex'=>10]);
开释锁:
就是直接删除这个key
锁超时:
lock的key有超不时间
新版的redis set命令就可以实现分布式锁,可以同时实现假如不存在时才去set和超不时间两项。
<?php $redis=new Redis(); $redis->connect("127.0.0.1",6379); //高并发时防止反复恳求 //渠道系统传递过来的key $lockKey='lock:18806767777&37781991111629092&taoshihan'; $resultKey='res:18806767777&37781991111629092&taoshihan'; //假如已经查询过值,可以直接返回 $info=$redis->get($resultKey); if($info){ exit($info); } //假如没有值的,猎取锁 $lock=$redis->set($lockKey, 1, ['nx', 'ex'=>10]); if($lock){ //恳求外部系统猎取结果,比方响应结果比力慢 sleep(8); $info='{"name":"taoshihan"}'; $ret=$redis->set($resultKey,$info); if($ret){ //删除锁 $redis->del($lockKey); exit($info); } } echo "请稍后重试!";
引荐学习:PHP教程
以上就是PHP怎样基于redis的分布式锁防止高并发反复恳求的具体内容,更多请关注百分百源码网其它相关文章!