分布式限流解决方案-Redis+Lua

本文介绍了如何使用Redis和Lua脚本实现分布式限流,防止黑客或恶意用户的高并发请求导致系统崩溃。通过限制每个用户在一秒钟内的请求数量,避免重复数据和慢查询拖垮系统。文章详细讲解了配置Redis依赖、编写Lua限流脚本、在Spring Boot中集成RedisTemplate以及使用AOP实现注解版限流的方法。
摘要由CSDN通过智能技术生成

分布式限流解决方案-Redis+Lua

1、分析

黑客或者一些恶意的用户为了攻击网站或者APP,通过并发用肉机并发或者死循环请求接口,从而导致系统出现宕机。

  • 针对新增数据的接口,会出现大量的重复数据,甚至垃圾数据会将数据库和CPU或者内存磁盘耗尽,直到数据库撑爆为止。
  • 针对查询的接口。一般是重点攻击慢查询,比如一个SQL是2S。只要一致攻击,就必然造成系统被拖垮,数据库查询全都被阻塞,连接一直得不到释放造成数据库无法访问。

一个用户在1秒钟之内,只允许请求n次。

2、Redis + Lua实现限流解决方案

2.1 redis依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<!--这里就是redis的核心jar包-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2 限流userLimit.lua脚本
-- 限流
-- 获取方法签名特征
local key = KEYS[1]
-- 调用脚本传入的限流大小
local limit = tonumber(ARGV[1])
-- 获取当前流量大小
local count = tonumber(redis.call('get',key) or "0")
-- 是否超出限流阈值
if count + 1 > limit then
    -- 拒绝服务
    return false
else
    -- 没有超过阈值
    -- 设置当前访问的数量 + 1
    redis.call("incr",key)
    -- 设置过期时间
    redis.call("expire",key,ARGV[2])
    return true
end
3.3 加载lua脚本的DefaultRedisScript对象
package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/16/12:48
 * @Description: 将lua脚本的内容加载出来放入到DefaultRedisScript
 */
@Configuration
public class LuaConfiguration {
   
    
    @Bean
    public DefaultRedisScript<Boolean> limitUserAccessLua() {
   
        // 初始化一个lua脚本的对象DefaultRedisScript
        DefaultRedisScript<Boolean> defaultRedisScript = new DefaultRedisScript<>();
        // 通过这个对象去加载lua脚本的位置 Class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南宫拾壹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值