laravel如何使用Redis实现分布式锁_Laravel Redis分布式锁实现方法
发布时间 - 2025-10-02 00:00:00 点击率:次Laravel通过Redis的SET命令结合NX和PX选项实现原子性加锁,使用唯一token标识进程,并借助Lua脚本安全释放锁,确保分布式环境下任务不重复执行。
Laravel 使用 Redis 实现分布式锁,核心是利用 Redis 的原子操作特性来保证同一时间只有一个进程能获取到锁。这在多服务器、队列任务或定时命令并发执行的场景中非常有用,避免重复处理造成数据异常。
1. 安装并配置 Redis 扩展
Laravel 默认支持 Redis,但需要确保已安装 predis/predis 或启用 PHP 的 Redis 扩展。
composer require predis/predis然后在 config/database.php 中确认 Redis 配置正确:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
2. 使用 Redis::set 实现原子加锁
Redis 的 SET 命令支持 NX(不存在时设置)和 PX(毫秒过期),可以原子性地实现加锁。
示例代码:
$lockKey = 'lock:send_report';
$ttl = 10000; // 锁过期时间,单位毫秒
$token = uniqid(); // 唯一标识当前进程
$locked = Redis::set($lockKey, $token, 'NX', 'PX', $ttl);
if (! $locked) {
// 获取锁失败,说明其他进程正在执行
return response('任务已在执行中', 423);
}
// 成功获取锁,开始执行任务
try {
// 你的业务逻辑,比如发送报表
dispatch(new SendReportJob());
} finally {
// 使用 Lua 脚本安全释放锁(防止删除别人的锁)
$script = <<<'LUA'
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
LUA;
Redis::eval($script, 1, $lockKey, $token);
}
3. 封装为可复用的锁服务
为了方便使用,可以封装一个简单的分布式锁类:
class DistributedLock
{
protected $key;
protected $token;
protected $ttl;
public function __construct($key, $ttl = 10000)
{
$this->key = "lock:{$key}";
$this->ttl = $ttl;
$this->token = uniqid();
}
public function acquire()
{
return Redis::set($this->key, $this->token, 'NX', 'PX', $this->ttl);
}
public function release()
{
$script = <<<'LUA'
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
LUA;
Redis::eval($script, 1, $this->key, $this->token);
}
}
使用方式:
$lock = new DistributedLock('import_data', 5000);
if (! $lock->acquire()) {
return '资源被占用';
}
try {
// 执行关键操作
} finally {
$lock->release();
}
4. 注意事项与最佳实践
使用 Redis 分布式锁时要注意以下几点:
- 设置合理的过期时间:避免死锁,但也不能太短导致任务未完成锁就释放
- 使用唯一 token 标识锁持有者:防止误删其他进程的锁
- 必须用 Lua 脚本释放锁:保证“判断+删除”的原子性
- 考虑 Redis 单点问题:生产环境建议使用 Redis Sentinel 或 Cluster 提高可用性
# php
# word
# laravel
# redis
# composer
# red
# lua
# 分布式
# sentinel
# 封装
# require
# Token
# 并发
# database
# 加锁
# 死锁
# 单点
# 可用性
# 但也
# 不存在
# 只有一个
# 已在
# 几点
# 这在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何打造高效商业网站?建站目的决定转化率
Laravel集合Collection怎么用_Laravel集合常用函数详解
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
如何用IIS7快速搭建并优化网站站点?
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
如何快速搭建高效WAP手机网站?
高端建站三要素:定制模板、企业官网与响应式设计优化
HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】
大型企业网站制作流程,做网站需要注册公司吗?
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
免费视频制作网站,更新又快又好的免费电影网站?
Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】
Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】
BootStrap整体框架之基础布局组件
如何破解联通资金短缺导致的基站建设难题?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
网站优化排名时,需要考虑哪些问题呢?
详解CentOS6.5 安装 MySQL5.1.71的方法
如何安全更换建站之星模板并保留数据?
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
浅析上传头像示例及其注意事项
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
如何制作一个表白网站视频,关于勇敢表白的小标题?
Laravel如何实现用户注册和登录?(Auth脚手架指南)
HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
如何用AI帮你把自己的生活经历写成一个有趣的故事?
微信推文制作网站有哪些,怎么做微信推文,急?
Laravel如何生成URL和重定向?(路由助手函数)
JavaScript中的标签模板是什么_它如何扩展字符串功能
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
如何批量查询域名的建站时间记录?
JS实现鼠标移上去显示图片或微信二维码
Swift中循环语句中的转移语句 break 和 continue
🚀拖拽式CMS建站能否实现高效与个性化并存?
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
JavaScript Ajax实现异步通信
java中使用zxing批量生成二维码立牌
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
Python图片处理进阶教程_Pillow滤镜与图像增强
浅述节点的创建及常见功能的实现


3. 封装为可复用的锁服务