[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] 基于redis的分布式锁防止高并发重复请求的更多相关文章
- 基于redis的分布式锁防止高并发重复请求
需求: 我们先举个某系统验证的列子:(A渠道系统,业务B系统,外部厂商C系统)(1)B业务系统调用A渠道系统,验证传入的手机.身份证.姓名三要素是否一致.(2)A渠道系统再调用外部厂商C系统.(3)A ...
- asp.net core mvc基于Redis实现分布式锁,C# WebApi接口防止高并发重复请求,分布式锁的接口幂等性实现
使用背景:在使用app或者pc网页时,可能由于网络原因,api接口可能被前端调用一个接口重复2次的情况,但是请求内容是一样的.这样在同一个短暂的时间内,就会有两个相同请求,而程序只希望处理第一个请求, ...
- 基于Redis的分布式锁真的安全吗?
说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...
- 基于redis的分布式锁实现
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
- 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...
- 转载:基于Redis实现分布式锁
转载:基于Redis实现分布式锁 ,出处: http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如 ...
- 基于redis的分布式锁的分析与实践
前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...
- python基于redis实现分布式锁
阅读目录 什么事分布式锁 基于redis实现分布式锁 一.什么是分布式锁 我们在开发应用的时候,如果需要对某一个共享变量进行多线程同步访问的时候,可以使用我们学到的锁进行处理,并且可以完美的运行,毫无 ...
- 基于Redis的分布式锁到底安全吗(下)?
2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...
随机推荐
- JS 实现
JavaScript 使用 HTML 中的脚本必须位于<script> 与 </script>标签之间. 脚本可被放置在 HTML 页面的 <body>和 < ...
- Linux相关集合
本篇概述 Linux xshell6 连接 Hadoop 启动关闭 Linux xshell6 连接相关问题 首先,虚拟机 得先能通成网(具体教程可百度) 然后,进行 本机 ip 的查询(xshell ...
- mssql sqlserver text、image字段类型无法使用DISTINCT的处理方法分享
转自: http://www.maomao365.com/?p=9775 摘要: 下文简述sqlserver数据库中 text image类型无法使用distinct的处理方法分享 实验环境:sql ...
- WebScraper for Mac(网站数据抓取软件) 4.10.2
WebScraper Mac版是一款Mac平台上通过使用将数据导出为JSON或CSV的简约应用程序,WebScraper Mac版可以快速提取与某个网页(包括文本内容)相关的信息.WebScraper ...
- last.jenkins 其他 一些知识点
时区不一致. jenkins的的时间和 系统时间不一致. 打开jenkins的[系统管理]---> [脚本命令行],在命令框中输入一下命令[时间时区设为 亚洲上海] System.setProp ...
- xen原理
目录:1. Xen的简介1.1 Xen的大体结构1.2 Xen对VM的称呼1.3 Xen对CPU和内存的虚拟化过程1.4 Xen对IO设备的虚拟化过程1.5 Linux Kernel对Xen的支持1. ...
- java异常处理机制详解
java异常处理机制详解 程序很难做到完美,不免有各种各样的异常.比如程序本身有bug,比如程序打印时打印机没有纸了,比如内存不足.为了解决这些异常,我们需要知道异常发生的原因.对于一些常见的异常,我 ...
- win7+vim搭建+verilog HDL IDE
参考地址:http://www.huangdc.com/421 参考文章为2016年,部分更新贴于文章内了 安装下载vim vim在win下叫gvim,下载地址:https://www.vim.org ...
- Java 程序员应在2019年学习的10条面向对象(OOP)设计原则
面向对象的设计原则 是 OOP 编程的核心,但是我看到大多数 Java 程序员都在追求诸如 Singleton 模式,Decorator 模式或 Observer 模式之类的设计模式,而对学习面向 ...
- 当接口请求体里的日期格式跟web页面日期格式不一致时,该如何处理呢?
首先引入Unix纪元时间戳的概念:即格林威治时间(GMT,Greenwich Mean Time)1970年1月1日00:00:00,到当前时间的秒数.单位为秒(s). 那么当前时间的Unix纪元时间 ...