SpringBoot使用Redis進(jìn)行限流功能實(shí)現(xiàn)
概述
Spring Boot中使用Redis實(shí)現(xiàn)限流功能是一種常見的做法,特別是在高并發(fā)場(chǎng)景下,限流可以有效防止系統(tǒng)過載,保證服務(wù)的穩(wěn)定性。
1. 限流的應(yīng)用場(chǎng)景
限流通常用于以下場(chǎng)景:
- API限流:防止API被惡意或過度調(diào)用,保護(hù)后端服務(wù)。
- 防止爬蟲:限制爬蟲的訪問頻率,防止數(shù)據(jù)被大量抓取。
- 秒殺系統(tǒng):在秒殺活動(dòng)中,限制用戶的請(qǐng)求頻率,防止系統(tǒng)崩潰。
- 防止DDoS攻擊:通過限流防止分布式拒絕服務(wù)攻擊。
2. Redis限流的實(shí)現(xiàn)原理
Redis限流的常見實(shí)現(xiàn)方式有:
- 計(jì)數(shù)器算法:通過Redis的
INCR命令實(shí)現(xiàn)簡(jiǎn)單的計(jì)數(shù)器限流。 - 滑動(dòng)窗口算法:通過Redis的有序集合(
ZSET)實(shí)現(xiàn)滑動(dòng)窗口限流。 - 令牌桶算法:通過Redis的
LIST或ZSET實(shí)現(xiàn)令牌桶限流。
下面我們以計(jì)數(shù)器算法為例,講解如何在Spring Boot中實(shí)現(xiàn)限流。
3. Spring Boot集成Redis實(shí)現(xiàn)限流
3.1 添加依賴
首先,在pom.xml中添加Spring Boot和Redis的依賴:
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Redis Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Lettuce Redis Client -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>3.2 配置Redis
在application.properties中配置Redis連接信息:
spring.redis.host=localhost spring.redis.port=6379
3.3 實(shí)現(xiàn)限流邏輯
我們可以通過自定義注解和AOP來實(shí)現(xiàn)限流功能。
3.3.1 自定義限流注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimiter {
String key(); // Redis的key
int limit(); // 限流次數(shù)
int expire(); // 過期時(shí)間(秒)
}3.3.2 實(shí)現(xiàn)AOP切面
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class RateLimiterAspect {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Around("@annotation(rateLimiter)")
public Object around(ProceedingJoinPoint joinPoint, RateLimiter rateLimiter) throws Throwable {
String key = rateLimiter.key();
int limit = rateLimiter.limit();
int expire = rateLimiter.expire();
// 獲取當(dāng)前請(qǐng)求的次數(shù)
Long count = redisTemplate.opsForValue().increment(key, 1);
if (count == 1) {
// 如果是第一次請(qǐng)求,設(shè)置過期時(shí)間
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
if (count > limit) {
// 超過限流次數(shù),拋出異?;蚍祷劐e(cuò)誤信息
throw new RuntimeException("請(qǐng)求過于頻繁,請(qǐng)稍后再試");
}
// 執(zhí)行目標(biāo)方法
return joinPoint.proceed();
}
}3.3.3 使用限流注解
在Controller中使用@RateLimiter注解:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class ApiController {
@RateLimiter(key = "api:limit:test", limit = 5, expire = 60)
@GetMapping("/test")
public String test() {
return "請(qǐng)求成功";
}
}4. 示例代碼解釋
- @RateLimiter注解:用于標(biāo)記需要限流的方法,指定限流的key、限制次數(shù)和過期時(shí)間。
- RateLimiterAspect切面:通過AOP攔截帶有@RateLimiter注解的方法,使用Redis的INCR命令實(shí)現(xiàn)計(jì)數(shù)器限流。
- RedisTemplate:用于操作Redis,實(shí)現(xiàn)計(jì)數(shù)器的自增和過期時(shí)間設(shè)置。
5. 運(yùn)行效果
- 當(dāng)請(qǐng)求
/api/test接口時(shí),每60秒內(nèi)最多允許5次請(qǐng)求。 - 如果超過5次請(qǐng)求,將拋出異常并返回錯(cuò)誤信息。
6. 總結(jié)
通過Spring Boot和Redis的結(jié)合,我們可以輕松實(shí)現(xiàn)限流功能。計(jì)數(shù)器算法是最簡(jiǎn)單的限流方式,適用于大多數(shù)場(chǎng)景。如果需要更復(fù)雜的限流策略(如滑動(dòng)窗口、令牌桶等),可以基于Redis的有序集合或列表實(shí)現(xiàn)。
在實(shí)際應(yīng)用中,限流策略的選擇應(yīng)根據(jù)具體業(yè)務(wù)需求進(jìn)行調(diào)整,以確保系統(tǒng)的穩(wěn)定性和高可用性。
到此這篇關(guān)于SpringBoot使用Redis進(jìn)行限流功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot Redis 限流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot+redis 實(shí)現(xiàn)分布式限流令牌桶的示例代碼
- 使用SpringBoot?+?Redis?實(shí)現(xiàn)接口限流的方式
- SpringBoot整合Redis并且用Redis實(shí)現(xiàn)限流的方法 附Redis解壓包
- SpringBoot中使用Redis對(duì)接口進(jìn)行限流的實(shí)現(xiàn)
- 基于SpringBoot+Redis實(shí)現(xiàn)一個(gè)簡(jiǎn)單的限流器
- SpringBoot使用Redis對(duì)用戶IP進(jìn)行接口限流的示例詳解
- Springboot使用redis實(shí)現(xiàn)接口Api限流的實(shí)例
- SpringBoot使用Redis對(duì)用戶IP進(jìn)行接口限流的項(xiàng)目實(shí)踐
- Springboot+Redis實(shí)現(xiàn)API接口限流的示例代碼
- Springboot使用redis實(shí)現(xiàn)接口Api限流的示例代碼
相關(guān)文章
SpringBoot集成Graphql Query實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了SpringBoot集成Graphql Query實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Java中的CAS無鎖機(jī)制實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java中的CAS無鎖機(jī)制實(shí)現(xiàn)原理詳解,無鎖機(jī)制,是樂觀鎖的一種實(shí)現(xiàn),并發(fā)情況下保證對(duì)共享變量值更改的原子性,CAS是Java中Unsafe類里面的方法,底層通過調(diào)用C語(yǔ)言接口,再通過cup硬件指令保證原子性,需要的朋友可以參考下2024-01-01
分享一個(gè)你不知道的Java異常實(shí)現(xiàn)的缺陷
Java中一個(gè)大家熟知的知識(shí)點(diǎn)就是異常捕獲,try...catch...finally組合,但是很多人不知道這里面有一個(gè)關(guān)于Java的缺陷,或者說是異常實(shí)現(xiàn)的一點(diǎn)不足之處。本文就通過一個(gè)很簡(jiǎn)單的實(shí)驗(yàn)給大家演示下效果玩玩兒,希望大家能覺得有趣2022-12-12
將Mybatis升級(jí)為Mybatis-Plus的詳細(xì)過程
本文詳細(xì)介紹了在若依管理系統(tǒng)(v3.8.8)中將MyBatis升級(jí)為MyBatis-Plus的過程,旨在提升開發(fā)效率,通過本文,開發(fā)者可實(shí)現(xiàn)系統(tǒng)功能無損升級(jí),同時(shí)享受MyBatis-Plus帶來的便捷特性,如代碼簡(jiǎn)化和性能優(yōu)化,需要的朋友可以參考下2025-04-04
idea已經(jīng)提交到遠(yuǎn)程分支,但需要本地和遠(yuǎn)程都回退到某一版本問題
這篇文章主要介紹了idea已經(jīng)提交到遠(yuǎn)程分支,但需要本地和遠(yuǎn)程都回退到某一版本問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
MyBatisPlus3.4.3版自動(dòng)生成代碼的使用過程
這篇文章主要介紹了MyBatisPlus3.4.3版自動(dòng)生成代碼的使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
SpringBoot integration實(shí)現(xiàn)分布式鎖的示例詳解
常規(guī)項(xiàng)目都是采用Redission來實(shí)現(xiàn)分布式鎖,進(jìn)行分布式系統(tǒng)中資源競(jìng)爭(zhēng)加鎖操作,偶然發(fā)現(xiàn)SpringBoot中的integration也實(shí)現(xiàn)多種載體的分布式鎖控制,下面我們就來看看具體實(shí)現(xiàn)方法吧2023-12-12

