高并发解决方案之 redis 分布式锁
背景:秒杀服务中要写一个定时任务:活动到期时给order微服务发送关闭订单的通知。这需要改变数据库表中的数据,而集群中服务是多节点的方式进行部署,会出现并发执行的情况,所以采用的redis的分布式锁的实现方式。
Redis 锁(setNx)
特点: 如果没有获取到锁,请求会被丢弃。 只适合 消息队列 和定时任务场景
点击查看代码
public function sendEndNotice()
{
$lock = new QueueLockLogic(LimitCFG::CLOSE_LOCK_KEY);
$lock_res = $lock->lock(LimitCFG::CLOSE_LOCK_KEY);
if (!$lock_res) return false;
//...
$res = $lock->unlock(LimitCFG::CLOSE_LOCK_KEY);
return $res;
}
//再附上一个应用于砍价服务中消息队列的
加锁:
$uniqueKey = "bargain:cmq:upOrderStatus:$storeId_$branchId_$orderId_$status";
$lock = new QueueLockLogic($uniqueKey);
$lockRes = $lock->lock($uniqueKey);
if (!$lockRes){
throw new ErrException(ExceCode::E13161);
}
.....
解锁:
$res = $lock->unlock($uniqueKey);
===================方法原型============================
namespace App\Models\Logic;
use Swoft\Redis\Redis;
use Swoft\App;
/**
* Class QueueLockLogic
* @package App\Models\Logic
*/
class QueueLockLogic
{
private $redis;
private $prefix;
/**
*
* @param
*/
public function __construct(string $redisPrefix)
{
$this->redis = App::getBean(Redis::class);
$this->prefix = $redisPrefix;
}
/**
* 获取redis键
*
* @param string $unique
* @return string
*/
public function getKey(string $unique): string
{
return $this->prefix . $unique;
}
/**
* 获取锁
* 返回:
* true: 说明获得锁,
* false: 说明获得锁失败
*
* @param string $key
* @param integer $expireTime
* @return boolean
*/
public function lock(string $key, int $ttl = 60): bool
{
//加锁
$res = $this->redis->setNx($key, time() + $ttl);
if ($res === 0) { //加锁失败
//检测锁是否过期
$expireTime = $this->redis->get($key);
if ($expireTime < time()) { //锁已过期,获取锁
$oldExpireTime = $this->redis->getSet($key, time() + $ttl); //在查询期间可能有别的进程加锁,也许已经加锁成功。
if ($oldExpireTime < time()) {//加锁成功
return true;
}//即便加锁失败,重置了key的值也相差无几可忽略
}
return false;
}
return true;
}
/**
* 解锁
* @param string $key
* @return bool
*/
public function unlock(string $key): bool
{
return $this->redis->delete($key) > 0;
}
}
高并发解决方案之 redis 分布式锁的更多相关文章
- java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱
java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱 redis数据库 Redis企业集群高级应用精品教程[图灵学院] Redis权威指南 利用redis + lua解决抢红包高并 ...
- asp.net core mvc基于Redis实现分布式锁,C# WebApi接口防止高并发重复请求,分布式锁的接口幂等性实现
使用背景:在使用app或者pc网页时,可能由于网络原因,api接口可能被前端调用一个接口重复2次的情况,但是请求内容是一样的.这样在同一个短暂的时间内,就会有两个相同请求,而程序只希望处理第一个请求, ...
- 漫谈Redis分布式锁实现
在Redis上,可以通过对key值的独占来实现分布式锁,表面上看,Redis可以简单快捷通过set key这一独占的方式来实现分布式锁,也有许多重复性轮子,但实际情况并非如此.总得来说,Redis实现 ...
- 七种方案!探讨Redis分布式锁的正确使用姿势
前言 日常开发中,秒杀下单.抢红包等等业务场景,都需要用到分布式锁.而Redis非常适合作为分布式锁使用.本文将分七个方案展开,跟大家探讨Redis分布式锁的正确使用方式.如果有不正确的地方,欢迎大家 ...
- 分布式缓存重建并发冲突和zookeeper分布式锁解决方案
如果缓存服务在本地的ehcache中都读取不到数据. 这个时候就意味着,需要重新到源头的服务中去拉去数据,拉取到数据之后,赶紧先给nginx的请求返回,同时将数据写入ehcache和redis中 分布 ...
- 用压测模拟并发、并发处理(synchronized,redis分布式锁)
使用工具:Apache an 测压命令: ab -n 100 -c 100 http://www.baidu.com -n代表模拟100个请求,-c代表模拟100个并发,相当于100个人同时访问 ab ...
- 使用Redis分布式锁处理并发,解决超卖问题
一.使用Apache ab模拟并发压测 1.压测工具介绍 $ ab -n 100 -c 100 http://www.baidu.com/ -n表示发出100个请求,-c模拟100个并发,相当是100 ...
- JAVA系统架构高并发解决方案 分布式缓存 分布式事务解决方案
JAVA系统架构高并发解决方案 分布式缓存 分布式事务解决方案
- Redis 分布式锁进化史(解读 + 缺陷分析)
Redis分布式锁进化史 近两年来微服务变得越来越热门,越来越多的应用部署在分布式环境中,在分布式环境中,数据一致性是一直以来需要关注并且去解决的问题,分布式锁也就成为了一种广泛使用的技术,常用的分布 ...
- 一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)(转)
近两年来微服务变得越来越热门,越来越多的应用部署在分布式环境中,在分布式环境中,数据一致性是一直以来需要关注并且去解决的问题,分布式锁也就成为了一种广泛使用的技术,常用的分布式实现方式为Redis,Z ...
随机推荐
- Winform帮助文档(C#打开chm定位到特定页面)国内最全总结写法。原文文档带翻译
下面比较啰嗦,只一句即可:Help.ShowHelp(null,"C:\help.hcm", HelpNavigator.Topic,"index.htm")方 ...
- python单机版自动化测试框架源代码(selenium+Appium+requests+unittest+Excel用例+HTMLTestRunner报告)
一.自动化测试框架: 1.框架和项目源代码下载 https://gitee.com/rmtic/autoTest 说明:框架可以支持web界面UI.安卓Android,ios苹果.接口API等自动化测 ...
- leetcode -- 旋转矩阵相关问题
给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 1: 给定 m ...
- 蓝桥杯训练赛二-1199 问题 E: 哥德巴赫曾猜测
题目描述 德国数学家哥德巴赫曾猜测:任何大于6的偶数都可以分解成两个素数(素数对)的和.但有些偶数可以分解成多种素数对的和,如: 10=3+7,10=5+5,即10可以分解成两种不同的素数对 输入 输 ...
- 吴恩达老师机器学习课程chapter06——支持向量机与核函数
吴恩达老师机器学习课程chapter06--支持向量机与核函数 本文是非计算机专业新手的自学笔记,高手勿喷. 本文仅作速查备忘之用,对应吴恩达(AndrewNg)老师的机器学期课程第十二章. 目录 吴 ...
- 接口设置ip跨域
// 允许跨域请求的地址'allowUrls' => [ 'http://localhost:8080', 'http://192.168.2.224', 'http://192.168.2.2 ...
- gauva cache
guava 的cache比较好用. 用户使用的对象是LoadingCache, 通过CacheBuilder来创建,通过 CacheLoader来根据key加载数据.而且可以定时刷新缓存(有访问 ...
- JDBC之Connection
Connection 目录 Connection Java连接MySQL Connection必备知识点 利用JDBC使用Connection 问题一:为什么Java操作数据库的连接不是越多越好 问题 ...
- Java-面向对象基础 对象和方法
// 定义属性 String nick; String color; int age;// 定义类的方法 public void eat(){ System.out.println("在吃东 ...
- 【2】locust性能测试原理分析+登录测试脚本+总结
login_per_test1.py #对登录功能进行单点性能测试(一组测试数据)#发送首页请求,通过locust进行性能测试from locust import HttpLocust,task,T ...