首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[PHP] 基于redis的分布式锁防止高并发重复请求

[PHP] 基于redis的分布式锁防止高并发重复请求

作者头像
唯一Chat
发布2019-10-23 19:54:15
1.4K0
发布2019-10-23 19:54:15
举报
文章被收录于专栏:陶士涵的菜地陶士涵的菜地

需求: 我们先举个某系统验证的列子:(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 "请稍后重试!";
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档