当前位置: 首页 > news >正文

在 EggJS 中实现 Redis 上锁

配置环境

下载 Redis

Windows

访问 https://github.com/microsoftarchive/redis/releases 选择版本进行下载 - 勾选 [配置到环境变量] - 无脑下一步并安装

在这里插入图片描述

命令行执行:redis-cli -v 查看已安装的 Redis 版本,能成功查看就表示安装成功啦~


Mac

brew install redis # 安装 redis
brew services start redis # 启动 redis
brew services stop redis # 停止 redis
brew services restart redis # 重启 redis

启动 Redis

打开任务管理器,找到 Redis 服务,点击启动即可

在这里插入图片描述



配置 EggJS 项目

  1. 安装依赖
pnpm i egg-redis

  1. 配置插件
// config/plugin.js
exports.redis = {enable: true,package: 'egg-redis',
};
// config/config.default.js
exports.redis = {client: {port: 6379, // Redis porthost: '127.0.0.1', // Redis hostpassword: '',db: 0,},
};

  1. 扩展 helper
// app/extend/helper.js
module.exports = {// 生成 redis 锁的控制器; val 为随机数, 防止解锁时误删其他请求的锁redisLockController(key, val = Math.random(), ttl = 5 * 60) {const app = this.app;return {// 上锁async lock() {// 使用 set 命令上锁并设置过期时间, 保证原子性const lockResult = await app.redis.set(key,val,'EX',ttl,'NX');return lockResult === 'OK';},// 解锁async unlock() {// 使用 lua 脚本校验锁并解锁, 保证原子性const script = `if redis.call('get', KEYS[1]) == ARGV[1] thenreturn redis.call('del', KEYS[1])elsereturn 0end`;// 使用 eval 命令执行 lua 脚本const unlockResult = await app.redis.eval(script, 1, key, val);return unlockResult === 1;},};},
};

  1. 使用 redis 上锁
// app/controller/home.js
const { Controller } = require('egg');module.exports = class HomeController extends Controller {async index() {const { id } = this.ctx.query;const result = await this.service.home.index(id);this.ctx.body = result;}
};
// app/service/home.js
const { Service } = require('egg');module.exports = class HomeService extends Service {async index(id = 0) {// 从 header 中获取 region 参数const region = this.ctx.get('region') || 'default';// 生成锁的 keyconst lockKey = `lock:${region}:${id}`;// 获取锁的控制器const { lock, unlock } = this.ctx.helper.redisLockController(lockKey);// 上锁const lockResult = await lock();// 上锁失败if (!lockResult) return { code: 500, msg: 'lock failed' };// 上锁成功, 执行业务逻辑let result;try {result = await this.mockSql(id);} catch (err) {result = { code: 500, msg: err.message };}// 解锁await unlock();// 返回结果return result;}// 模拟数据库查询async mockSql(id) {// 2s 后返回结果return new Promise((resolve) => {setTimeout(() => {resolve({code: 200,msg: 'success',data: { id, desc: 'egg is very good', time: Date.now() },});}, 2000);});}
};



模拟抢锁

开两个浏览器访问 http://localhost:7001 即可模拟抢锁的场景


相关文章:

在 EggJS 中实现 Redis 上锁

配置环境 下载 Redis Windows 访问 https://github.com/microsoftarchive/redis/releases 选择版本进行下载 - 勾选 [配置到环境变量] - 无脑下一步并安装 命令行执行:redis-cli -v 查看已安装的 Redis 版本,能成功查看就表示安装成功啦~ Mac brew i…...

Unity-场景

创建场景 创建新的场景后: 文件 -> 生成设置 -> Build中的场景 -> 将项目中需要使用的场景拖进去 SceneTest public class SceneTest : MonoBehaviour {// Start is called before the first frame updatevoid Start(){// 两个类: 场景类、场…...

MATLAB R2023b for Mac 中文

MATLAB R2023b 是 MathWorks 发布的最新版本的 MATLAB,适用于进行算法开发、数据可视化、数据分析以及数值计算等任务的工程师和科学家。它包含了一系列新增功能和改进,如改进了数据导入工具,增加了对数据帧和表格对象的支持,增强…...

01 MyBatisPlus快速入门

1. MyBatis-Plus快速入门 版本 3.5.31并非另起炉灶 , 而是MyBatis的增强 , 使用之前依然要导入MyBatis的依赖 , 且之前MyBatis的所有功能依然可以使用.局限性是仅限于单表操作, 对于多表仍需要手写 项目结构: 先导入依赖,比之前多了一个mybatis-plus…...

HarmonyOS 应用开发入门

HarmonyOS 应用开发入门 前言 DevEco Studio Release版本为:DevEco Studio 3.1.1。 Compile SDK Release版本为:3.1.0(API 9)。 构建方式为 HVigor,而非 Gradle。 最新版本已不再支持 (”Java、JavaScrip…...

【机器学习300问】9、梯度下降是用来干嘛的?

当你和我一样对自己问出这个问题后,分析一下!其实我首先得知道梯度下降是什么,也就它的定义。其次我得了解它具体用在什么地方,也就是使用场景。最后才是这个问题,梯度下降有什么用?怎么用? 所以…...

第13章 1 进程和线程

文章目录 程序和进程的概念 p173函数式创建子进程Process类常用的属性和方法1 p175Process类中常用的属性和方法2 p176继承式创建子进程 p177进程池的使用 p178并发和并行 p179进程之间数据是否共享 p180队列的基本使用 p180使用队列实现进程之间的通信 p182函数式创建线程 p18…...

什么是中间件?

文章目录 为什么需要中间件?中间件生态漫谈数据库中间件读写分离分库分表引进数据库中间件MyCat 服务端代理模式ShardingJDBC 客户端代理模式 总结 IT 系统从单体应用逐渐向分布式架构演变,高并发、高可用、高性能、分布式等话题变得异常火热&#xff0c…...

汽车售后服务客户满意度调查报告

本文由群狼调研(长沙旅行社满意度调查)出品,欢迎转载,请注明出处。汽车售后服务客户满意度调查报告通常包括以下内容: 1.调研概况:介绍调研的目的、背景和范围,包括调研的时间、地点和样本规模等…...

初始RabbitMQ(入门篇)

消息队列(MQ) 本质上就是一个队列,一个先进先出的队列,队列中存放的内容是message(消息),是一种跨进程的通信机制,用于上下游传递消息, 为什么使用MQ: 削峰填谷: MQ可以很好的做一个缓冲机制,例如在一个系统中有A和B两个应用,A是接收用户的请求的,然后A调用B进行处理. 这时…...

JVM:Java类加载机制

Java类加载机制的全过程: 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始, 这是为了支持Java…...

要经历痛苦,才能在赚钱路上觉醒!

新手赚钱,一个秘诀就够了! 黎明前的黑暗实际是最漫长的,就如同开发进度99%到100%这个过程尤其漫长。赚钱的路上起初就是黑暗,不断地摸索最终才能走出迷雾,真正的迎接朝阳。如果有一段路程,十来公里的路线&a…...

LeetCode 第381场周赛个人题解

目录 100191. 输入单词需要的最少按键次数 I 原题链接 题目描述 思路分析 AC代码 100188. 按距离统计房屋对数目 I 原题链接 题目描述 思路分析 AC代码 100192. 输入单词需要的最少按键次数 II 原题链接 题目描述 思路分析 AC代码 100213. 按距离统计房屋对数目…...

数据结构之二叉树的性质与存储结构

数据结构之二叉树的性质与存储结构 1、二叉树的性质2、二叉树的存储结构 数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,…...

机器视觉检测设备在连接器外观缺陷检测中的应用

作为传输电流或信号连接两个有源器件的器件,连接器被广泛应用于各个行业,从手机、平板、电脑,到冰箱、空调、洗衣机,再到汽车、国防、航空,处处是它的所在。每个电子产品少了连接器将无法运作,因此&#xf…...

ChatGPT vs 文心一言(AI助手全面比较)

随着人工智能的不断发展,ChatGPT(OpenAI)和文心一言都代表了当前先进的自然语言处理技术。它们在智能回复、语言准确性和知识库丰富度等方面都有各自的优势。在下面的比较中,我们将从多个角度探讨这两个AI助手,帮助你更…...

MSPM0L1306例程学习-UART部分(2)

MSPM0L1306例程学习系列 1.背景介绍 写在前边的话: 这个系列比较简单,主要是围绕TI官网给出的SDK例程进行讲解和注释。并没有针对模块的具体使用方法进行描述。所有的例程均来自MSPM0 SDK的安装包,具体可到官网下载并安装: https://www.ti…...

Baichuan2百川模型部署的bug汇总

1.4bit的量化版本最好不要在Windows系统中运行,大概原因报错原因是bitsandbytes不支持window,bitsandbytes-windows目前仅支持8bit量化。 2. 报错原因是机器没有足够的内存和显存,offload_folder设置一个文件夹来保存那些离线加载到硬盘的权…...

ChatGPT 如何解决 “Something went wrong. lf this issue persists ….” 错误

Something went wrong. If this issue persists please contact us through our help center at help.openai.com. ChatGPT经常用着用着就出现 “Something went wrong” 错误,不管是普通账号还是Plus账号,不管是切换到哪个节点,没聊两次就报…...

怎么移除WordPress后台工具栏的查看站点子菜单?如何改为一级菜单?

默认情况下,我们在WordPress后台想要访问前端网站,需要将鼠标移动到左上角的站点名称,然后点击下拉菜单中的“查看站点”才行,而且还不是新窗口打开。那么有没有办法将这个“查看站点”子菜单变成一级菜单并显示在顶部管理工具栏中…...

3分钟快速上手:免费高效的Elasticsearch可视化工具Elasticvue终极指南

3分钟快速上手:免费高效的Elasticsearch可视化工具Elasticvue终极指南 【免费下载链接】elasticvue Elasticsearch gui for the browser 项目地址: https://gitcode.com/gh_mirrors/el/elasticvue 你是否曾经为复杂的Elasticsearch集群管理而烦恼&#xff1f…...

阿联酋人工智能大学:AI能在战争迷雾中做出理性判断吗?

这项由阿联酋穆罕默德本扎耶德人工智能大学和美国马里兰大学共同完成的研究发表于2026年3月,论文编号为arXiv:2603.16642v1。有兴趣深入了解的读者可以通过该编号查询完整论文。在人类历史上,预测战争走向一直是个极其困难的任务。就像我们很难在暴风雨中…...

GaussDB JDBC SSL加密全攻略:从零配置到生产环境最佳实践

GaussDB JDBC SSL加密全攻略:从零配置到生产环境最佳实践 在数据驱动的时代,数据库连接的安全性已成为企业级应用不可忽视的生命线。作为华为云推出的分布式关系型数据库,GaussDB在金融、政务等对安全性要求极高的场景中广泛应用。而JDBC作为…...

避坑指南:Xdocreport模板制作中的5个常见错误及解决方案

Xdocreport实战避坑指南:模板制作中的5个高频错误与深度解决方案 在Java生态中处理动态Word文档生成时,Xdocreport凭借其与MS Office的无缝兼容性和模板灵活性,已成为企业级文档自动化的重要工具。但许多开发者在从Freemarker迁移到Xdocrepor…...

别再花钱买云API了!手把手教你用Docker+Ollama在本地免费跑通Strix渗透测试

零成本打造企业级渗透测试环境:DockerOllama本地化实战指南 当安全团队每月收到云服务商五位数的API账单时,当关键测试任务因网络抖动被迫中断时,越来越多的技术决策者开始重新审视渗透测试的基础架构。本文将揭示如何用消费级硬件构建媲美商…...

Win11Debloat:一键清理Windows 11,让你的电脑重回清爽状态

Win11Debloat:一键清理Windows 11,让你的电脑重回清爽状态 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本,用于从Windows中移除预装的无用软件,禁用遥测,从Windows搜索中移除Bing,以及执行各种其…...

3大核心步骤打造专属翻译引擎:Zotero PDF Translate高级扩展指南

3大核心步骤打造专属翻译引擎:Zotero PDF Translate高级扩展指南 【免费下载链接】zotero-pdf-translate 支持将PDF、EPub、网页内容、元数据、注释和笔记翻译为目标语言,并且兼容20多种翻译服务。 项目地址: https://gitcode.com/gh_mirrors/zo/zoter…...

RT-DETR实战入门:从环境搭建到YOLO数据集转换COCO格式

1. RT-DETR环境搭建:避坑指南 刚接触RT-DETR时,环境配置是最容易翻车的第一关。我最初尝试时,因为没注意torch版本兼容性问题,浪费了整整两天时间。这里分享几个关键细节: 首先是PyTorch版本选择。官方推荐使用torch 2…...

Win32下用libigl+GLFW3渲染3D模型的完整配置指南(附常见错误排查)

Win32下用libiglGLFW3渲染3D模型的完整配置指南(附常见错误排查) 在Windows平台进行3D图形开发时,libigl与GLFW3的组合为开发者提供了强大的工具集。libigl作为一个轻量级的C几何处理库,与GLFW3这一跨平台的OpenGL窗口管理库结合…...

从串口通信到内存总线:手把手拆解‘波特率’、‘比特率’与‘总线带宽’的异同与实战计算

从串口通信到内存总线:深度解析波特率、比特率与总线带宽的实战差异 在嵌入式开发和计算机体系结构领域,数据传输速率的计算是工程师日常工作中无法绕开的基础技能。但令人困惑的是,同样的"速率"概念在不同场景下却有着完全不同的…...