????個人主頁:哈__
期待您的關(guān)注?
本文介紹SpringBoot整合Redis并且進行接口的限流,文章主要介紹的是一種思想,具體代碼還要結(jié)合實際。
一、Windows安裝Redis
Redis的解壓包我放在了百度網(wǎng)盤上,有需要的可以下載。
Redis-x64-3.0.504 解壓碼:uhwj
二、啟動Redis
我們在本地解壓下載的Redis壓縮包,打開解壓后的目錄,首先啟動redis-server.exe,之后在啟動redis-cli.exe。
啟動成功截圖如下。
三、SpringBoot整合Redis?
1.引入依賴?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.添加配置文件application.yml
?我們并沒有設(shè)置密碼所以不用配置。
spring:
redis:
host: 127.0.0.1
port: 6379
3.創(chuàng)建RedisController
我們現(xiàn)在是介紹思想,所以傳入了一個用戶的id來判斷是哪一個用戶訪問的接口。我們對redis中保存的key為用戶id的鍵值對進行一個自增操作,然后返回這個自增后的值,這個值代表的就是我們在十秒鐘內(nèi)訪問接口的次數(shù)。每次訪問我們都重新設(shè)置這個鍵值對的有效時間,如果值大于5說明我們訪問的次數(shù)已經(jīng)達到了系統(tǒng)對個人十秒鐘內(nèi)訪問次數(shù)的限制了,就不可以執(zhí)行我們的業(yè)務(wù)邏輯。
@Resource
private RedisTemplate<String, String> redisTemplate;
@GetMapping("/test2")
public String test2(String id){
Long increment = redisTemplate.opsForValue().increment(id);
redisTemplate.expire(id,10,TimeUnit.SECONDS);
if(increment > 5){
return "不可以訪問,訪問次數(shù)為"+increment;
}
return "可以訪問,訪問次數(shù)為"+increment;
}
之后啟動我們的SpringBoot項目。我這里使用的是PostMan進行的接口測試。
進行第一次訪問。
第二次。
?
第五次 。
第六次。第六次可以看到接口的返回值為不可以訪問,說明我們的訪問次數(shù)已經(jīng)上限了,這時候就要等十秒后再次訪問了。
?
四、Redis限流的幾種方法?
1.基于Redis的數(shù)據(jù)結(jié)構(gòu)zset(滑動窗口)
思想比較容易接收,我們定一個這樣一個key為limit的列表,每當(dāng)我們發(fā)送一次請求的時候,我們向這個列表當(dāng)中添加當(dāng)前的時間戳(前提是沒有被限流),當(dāng)然,在我們進行數(shù)據(jù)的添加之前需要進行是否需要進行限流。我們設(shè)定intervalTime為限流的時間間隔,我們從limit列表中獲取我們訪問接口的時間currentTIme-intervalTime,這樣我們判斷一下(currentTIme-intervalTime,currentTime)范圍內(nèi)的時間戳個數(shù),也就是我們請求的次數(shù),這樣就能判斷是否超過限制了。這里我用一張圖來表示。
既然叫做滑動窗口,那這個窗口的大小就是我們進行限流的時間間隔,這個窗口在我們的時間軸上進行移動。
代碼如下:
@GetMapping("/test3")
public String test3(){
int intervalTime = 10;
Long currentTime = new Date().getTime();
if(Boolean.TRUE.equals(redisTemplate.hasKey("limit"))) {
Integer count = Objects.requireNonNull(redisTemplate.opsForZSet().rangeByScore("limit", currentTime - intervalTime, currentTime)).size();
if (count != null && count > 5) {
return "每分鐘最多只能訪問5次";
}
}
redisTemplate.opsForZSet().add("limit", UUID.randomUUID().toString(),currentTime);
return "訪問成功";
}
?2.基于Redis的令牌桶算法
這個就好理解了,一個筐子里十個蘋果大家都去拿,拿到了就可以吃,拿不到就等著別人放。在Redis里我們在一個列表里放令牌,用戶訪問接口去嘗試拿這個令牌,拿到了就能訪問接口,拿不到就進行限流,當(dāng)然除了拿令牌之外還放令牌,我們通過定時任務(wù)向列表內(nèi)放令牌。文章來源:http://www.zghlxwxcb.cn/news/detail-845762.html
@GetMapping("/test3")
public String test3(){
Object result = redisTemplate.opsForList().leftPop("limit_list");
if(result == null){
return "當(dāng)前令牌桶中無令牌,無法訪問";
}
return "訪問成功";
}
@Scheduled(fixedDelay = 100,initialDelay = 0)
public void setLimitListTask(){
redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());
}
定時任務(wù)到底如何使用,大家可以自行搜索一下。還有一些其他的方式本文就不在介紹了。文章來源地址http://www.zghlxwxcb.cn/news/detail-845762.html
到了這里,關(guān)于【Spring】SpringBoot整合Redis,用Redis實現(xiàn)限流(附Redis解壓包)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!