当前位置:网站首页>封装一个koa分布式锁中间件来解决幂等或重复请求的问题
封装一个koa分布式锁中间件来解决幂等或重复请求的问题
2022-07-03 09:46:00 【InfoQ】
import ioredis from 'ioredis'
import { REDIS_CONF } from '../config/db'
const { password, port, host } = REDIS_CONF
class Redis {
client
constructor() {
this.client = new ioredis({
port,
host,
password
})
this.client.on('error', (err) => console.log(err))
}
//添加数据
async set(key: string, value: any, time?: number | string) {
//判断value值是否是对象类型
if (typeof value === 'object') {
value = JSON.stringify(value)
}
//time为过期时间,可选
if (time) {
await this.client.set(key, value, 'EX', time)
} else {
await this.client.set(key, value)
}
}
async get(key: string) {
const data = await this.client.get(key)
return data
}
async delete(key: string) {
await this.client.del(key)
}
}
const redis = new Redis()
export default redis
import Redlock from 'redlock'
import redis from './redis'
const redlock = new Redlock([redis.client], { retryCount: 0 })
export default redlock
import { Middleware } from 'koa'
import { Lock } from 'redlock'
import redlock from '../db/redlock'
import { error } from '../utils/Response'
//这里isByUser为true则由用户id+请求地址作为key上锁,即:此接口不允许一个用户同时更改同一资源(参数不同也不行)
//isByUser默认为false则由全部参数+用户id+地址作为key上锁,即:此接口不允许一个用户同时以同一参数更改同一资源(拦截重复请求)
const idempotent = (isByUser: boolean = false) => {
const Redlock: Middleware = async (ctx, next) => {
let id: string
//这里的ctx.user是我之前配置的中间件,用于解析用户携带token的参数,来辨别用户和获取用户参数,里面存放用户的个人信息
//有的接口不需要鉴权认证,所以ctx.user.id就会报错则id以空字符串输出
/*这里为什么要解析出id而不是直接拿token呢?因为一个用户可以有多个token,但一个用户只有一个id
如果拿token作为标识,不同token的同一用户也会成功上锁,就形成了一个用户多次获得了锁的情况
但由于id的独立性,所以id不同,就表示为不同的用户了
*/
try {
id = ctx.user.id
} catch (error) {
id = ''
}
let lock: Lock | null = null
try {
if (isByUser) {
//上锁
lock = await redlock.acquire([`${id}:${ctx.URL}`], 10000)
} else {
const body = JSON.stringify(ctx.request.body)
console.log(`${id}:${ctx.URL}:${body}`)
lock = await redlock.acquire([`${id}:${ctx.URL}:${body}`], 10000)
}
} catch (err) {
//如果抛出错误表示上锁失败,表示有重复请求正在操作
//这里的error()函数是我封装的返回错误的函数里面调用了ctx.throw所以报错会立即返回,后面的next不会继续进行
error(ctx, 500, '请求正在进行,请勿重复提交')
}
await next()
//后面的中间件全部执行完就可以释放锁了
await lock!.release()
}
return Redlock
}
export default idempotent





边栏推荐
- The highest monthly salary of 18K has a good "mentality and choice", and success is poor "seriousness and persistence"~
- 那些一门心思研究自动化测试的人,后来怎样了?
- 8年测试工程师总结出来的《测试核心价值》与《0基础转行软件测试超全学习指南》
- . Net core - a queuing system for wechat official account
- Commonly used discrete random distribution
- Programming examples of stm32f1 and stm32subeide -tm1637 drives 4-bit 7-segment nixie tubes
- 【Proteus仿真】74HC154 四线转12线译码器组成的16路流水灯
- IIS修改配置信息后不生效
- C language project: student achievement system
- Snownlp emotion analysis
猜你喜欢
Probability theory: application of convolution in calculating moving average
QT: QSS custom qtableview instance
嵌入式软件测试怎么实现自动化测试?
Software testing e-commerce projects that can be written into your resume, don't you come in and get it?
Exclusive analysis | truth about resume and interview
8年测试工程师总结出来的《测试核心价值》与《0基础转行软件测试超全学习指南》
Software testing redis database
MAUI Developer Day in GCR
Some abilities can't be learned from work. Look at this article, more than 90% of peers
How to realize automatic testing in embedded software testing?
随机推荐
公司里只有一个测试是什么体验?听听他们怎么说吧
QT: QSS custom qtoolbar and qtoolbox instances
Programming examples of stm32f1 and stm32subeide -tm1637 drives 4-bit 7-segment nixie tubes
嵌入式软件测试怎么实现自动化测试?
Hard goods | write all the codes as soon as you change the test steps? Why not try yaml to realize data-driven?
redis那些事儿
那些一門心思研究自動化測試的人,後來怎樣了?
The element form shows the relationship between elementary transformation and elementary matrix
How can UI automated testing get out of trouble? How to embody the value?
测试理论概述
Activity and fragment lifecycle
Clion debug
公司测试部门来了个00后卷王之王,老油条感叹真干不过,但是...
The five-year itch of software testing engineers tells the experience of breaking through bottlenecks for two years
字节跳动大裁员,测试工程师差点遭团灭:大厂招人背后的套路,有多可怕?
TypeScript学习总结
Game test related tests a hero's skills (spring moves are asked more questions)
T5 attempt
What kind of living condition is a tester with a monthly salary of more than 10000?
UI自动化测试如何走出困境?价值又如何体现?