高并发解决方案之 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 ...
随机推荐
- sqlalchemy+pandas:错误 'OptionEngine' object has no attribute 'execute','str' object has no attribute '_execute_on_connection'
场景:使用 sqlalchemy+pandas 1. 'OptionEngine' object has no attribute 'execute' import pandas as pd fro ...
- wpf dataGrid 获取单元格,并对单元格中的对象操作
先上图: 要求:对第一行的"选项内容举例..."的控件进行隐藏,如下: 前端代码: <Window x:Class="DataGridPractice.MainWi ...
- mysql表关联更新
UPDATE enterprise_test t1, enterprise_development_relation t2 SET t1.development_area_id = t2.develo ...
- Error building Player because scripts had compiler errors
报错信息如下: Error building Player because scripts had compiler errors Build completed with a result of ' ...
- WPF窗体图标设置
WPF程序在编写结束后,界面没有图标,影响美观性.今天在添加图标的时候,一直报错,然后通过查找资料,将这个问题解决,现在将主要步骤记录如下; 准备好图标文件,注意文件格式应该为ico格式文件.有一个在 ...
- Ubuntu下CodeBlocks控制台程序中文显示乱码解决问题
今天在CodeBlocks下折腾来半天,终于把中文乱码给解决了,其实很简单. 在环境设置里进行如下设置:把Terminal to launch console programs那个选项改成gnome- ...
- 【stm32】的PWM外设|学习笔记
PWM简单理解就是生成PWM方波,主要可控的参数有周期,占空比,极性. stm32内置PWM生成器,我想应该是用TIM加比较器来实现的吧,那么如何实现stm32输出PWM波呢? 一.得知道那些IO可以 ...
- Vue后台管理项目中解决需要配置多个端口号问题
背景 登录接口:http://39.98.123.211:8170/ 商品接口:http://39.98.123.211:8510/ 可见前面是地址是一致的,但是端口号不一样. 这就会导致,登录进得去 ...
- vscode 部分替换(正则替换)
1. 数字 \d{n} 2. 数字和字母 [A-Za-z0-9]{n} 常用运算符与表达式 ^ 开始 () 域段 [] 包含,默认是一个字符长度 [^] 不包含,默认是一个字符长度 {n,m} 匹配长 ...
- 881. 救生艇 (Medium)
问题描述 881. 救生艇 (Medium) 给定数组 people . people[i] 表示第 i 个人的体重 , 船的数量不限,每艘船可以承载的最大重量为 limit. 每艘船最多可同时载两人 ...