基于Redis+lua 防止用户请求重复提交
Posted Dream_it_possible!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Redis+lua 防止用户请求重复提交相关的知识,希望对你有一定的参考价值。
需求
一个用户3s内只能请求指定方法一次,例如发验证码场景。
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
lua 脚本
用keys 来获取列表里的参数,下标从1开始, 用ARGV获取全局变量,下标从1 开始。
return redis.call('set', KEYS[1], 1, 'ex', ARGV[1], 'nx');
此脚本的意思是: 通过setNx命令设置一个key=KEYS[1], value=1, 失效时间为 ARGV[1]
package com.example.prevent.controller;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
/**
* @decription:
* @author:
* @date: 2021/6/2 19:54
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@PostMapping(value = "/submit")
public boolean isReSubmit() {
String key = "user_id";
Integer expire = 3;
ArrayList<String> keys = Lists.newArrayList(key);
String result = stringRedisTemplate.execute(setNxWithExpireTime, keys, expire.toString());
return !"ok".equalsIgnoreCase(result);
}
private RedisScript<String> setNxWithExpireTime = new DefaultRedisScript<>(
"return redis.call('set', KEYS[1], 1, 'ex', ARGV[1], 'nx');",
String.class
);
}
第一次请求:
再次快速请求:
3s 的响应间隔时间内,是不允许再次重复提交!
以上是关于基于Redis+lua 防止用户请求重复提交的主要内容,如果未能解决你的问题,请参考以下文章