SpringBoot整合Redis實現(xiàn)刷票過濾功能
引言
隨著互聯(lián)網的不斷發(fā)展,網站或APP的用戶流量增加,也衍生出了一些惡意刷量等問題,給數(shù)據(jù)分析及運營帶來極大的困難,出現(xiàn)的刷票問題更是造成了嚴重的經濟損失,所以網站或APP對惡意刷票進行過濾是十分必要的。Redis提供了很好的解決方案,其提供的內存存儲和Key-Value的存儲結構,能夠高效地實現(xiàn)刷票過濾。
本文主要介紹如何使用SpringBoot和Redis實現(xiàn)刷票過濾,自定義同一IP每天刷票不得超過次數(shù)。
一、概述
本文主要分為以下幾個模塊:
1.開發(fā)環(huán)境
2.使用Redis存儲數(shù)據(jù)
3.使用SpringBoot開發(fā)應用
4.實現(xiàn)同一IP每天刷票不得超過次數(shù)
二、技術選型
SpringBoot2.2.5.RELEASE
Spring5.2.4.RELEASE
JDK8
Redis
三、搭建開發(fā)環(huán)境
1.安裝JDK8
2.安裝Redis(版本不限,最好使用穩(wěn)定版)
3.新建SpringBoot項目
使用IDEA新建SpringBoot項目
四、使用Redis存儲數(shù)據(jù)
1. 在pom.xml中加入Redis依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2.在application.yml中配置Redis
spring: redis: host: 127.0.0.1 port: 6379
3. 在RedisConfig.java中配置RedisTemplate和StringRedisTemplate
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){ StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); stringRedisTemplate.setConnectionFactory(redisConnectionFactory); return stringRedisTemplate; } }
五、使用SpringBoot開發(fā)應用
1.在pom.xml中加入SpringBoot依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2.新建Controller
@RestController @RequestMapping("/vote") public class VoteController { private final StringRedisTemplate redisTemplate; public VoteController(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } /** * 投票接口 * @param ip * @return */ @PostMapping("/submit") public String submit(@RequestParam String ip){ String key = "ip:" + ip; // 先判斷是否已經投票,如果已經投票,則返回 if(redisTemplate.opsForValue().get(key) != null){ return "您已經投過票了!"; } // 獲取當天的日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String date = sdf.format(new Date()); // 拼接當天投票的key String voteKey = "vote:" + date; // 將IP添加到Set中,記錄當天所有投票的IP redisTemplate.opsForSet().add(voteKey,ip); // 獲取當天已經投票的IP數(shù)量 long voteCount = redisTemplate.opsForSet().size(voteKey); // 判斷是否超過投票限制 if(voteCount > 10){ return "您今天的投票數(shù)已經用盡!"; } // 記錄已經投票,設置過期時間為1天 redisTemplate.opsForValue().set(key,"已經投票", 1, TimeUnit.DAYS); return "投票成功!"; } }
六、 實現(xiàn)同一IP每天刷票不得超過次數(shù)
1. 在VoteController的submit接口中實現(xiàn)同一IP每天刷票不得超過次數(shù)
每次投票時,先通過Redis查看是否已經投過票,如果已經投過票,則返回“您已經投過票了!”,否則將該IP添加到當天投票的Set中,再通過Redis查看當天投票的IP數(shù)量是否超過設定的閾值,如果超過則返回“您今天的投票數(shù)已經用盡!”,否則記錄已經投票,并將該條記錄設置為1天后過期。
上述邏輯可以采用Redis提供的Set和過期時間來完成,便捷高效。
2. 優(yōu)化方案
上述實現(xiàn)在高并發(fā)情況下可能存在問題,比如多個用戶同時投票,從而同時訪問Redis,產生并發(fā)問題或者性能問題,為此可以通過Redis的分布式鎖或者使用Redisson等第三方庫來解決。
下面簡單介紹一下使用Redisson來實現(xiàn)分布式鎖。
a. 在pom.xml中加入Redisson依賴
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.12.6</version> </dependency>
b. 在application.yml中加入Redisson配置
spring: redis: host: 127.0.0.1 port: 6379 database: 0 ????redisson: address: redis://127.0.0.1:6379
c. 新建RedissonConfig.java
@Configuration public class RedissonConfig { @Autowired private Environment env; @Bean(destroyMethod = "shutdown") RedissonClient redisson() throws IOException { // use "redis://" as the protocol Config config = new Config(); config.useSingleServer().setAddress(env.getProperty("redisson.address")); return Redisson.create(config); } }
d. 在VoteController中加入Redisson分布式鎖
@RestController @RequestMapping("/vote") public class VoteController { private final StringRedisTemplate redisTemplate; private final RedissonClient redissonClient; public VoteController(StringRedisTemplate redisTemplate, RedissonClient redissonClient) { this.redisTemplate = redisTemplate; this.redissonClient = redissonClient; } /** * 投票接口 * @param ip * @return */ @PostMapping("/submit") public String submit(@RequestParam String ip){ String key = "ip:" + ip; // 使用Redisson加鎖 RLock lock = redissonClient.getLock(key); lock.lock(); try { // 先判斷是否已經投票,如果已經投票,則返回 if (redisTemplate.opsForValue().get(key) != null) { return "您已經投過票了!"; } // 獲取當天的日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String date = sdf.format(new Date()); // 拼接當天投票的key String voteKey = "vote:" + date; // 將IP添加到Set中,記錄當天所有投票的IP redisTemplate.opsForSet().add(voteKey, ip); // 獲取當天已經投票的IP數(shù)量 long voteCount = redisTemplate.opsForSet().size(voteKey); // 判斷是否超過投票限制 if (voteCount > 10) { return "您今天的投票數(shù)已經用盡!"; } // 記錄已經投票,設置過期時間為1天 redisTemplate.opsForValue().set(key, "已經投票", 1, TimeUnit.DAYS); return "投票成功!"; } finally { lock.unlock(); } } }
以上是使用Redisson實現(xiàn)分布式鎖的思路及代碼,從而在高并發(fā)情況下,避免了多個用戶同時對Redis進行訪問的并發(fā)問題。
七、總結
本文介紹了如何使用SpringBoot和Redis實現(xiàn)刷票過濾,自定義同一IP每天刷票不得超過次數(shù)的功能。
通過使用Redis的Set和過期時間,實現(xiàn)了同一IP每天刷票不得超過次數(shù)的限制,并且代碼簡單高效。
在高并發(fā)情況下,通過使用Redisson等庫實現(xiàn)分布式鎖,避免了多個用戶同時訪問Redis的性能問題。
在實際應用中,除了IP限制和過期時間設置外,還可以根據(jù)具體需求,對投票做更細粒度的控制,比如設置對投票用戶的身份驗證、對投票的時間和場次進行限制等等。
最后,需要注意的是,防范惡意刷票是非常重要的,但是過度的限制可能也會造成用戶體驗不佳,需要在保障數(shù)據(jù)安全的前提下,兼顧用戶體驗的優(yōu)化。
本文主要介紹了如何使用SpringBoot和Redis實現(xiàn)刷票過濾,自定義同一IP每天刷票不得超過次數(shù)的功能。同時,還對高并發(fā)情況下可能存在的問題進行了分析,并提出了一些優(yōu)化的方案。
到此這篇關于SpringBoot整合Redis實現(xiàn)刷票過濾功能的文章就介紹到這了,更多相關SpringBoot Redis刷票過濾內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
如何讓java只根據(jù)數(shù)據(jù)庫表名自動生成實體類
今天給大家?guī)淼闹R是關于Java的,文章圍繞著如何讓java只根據(jù)數(shù)據(jù)庫表名自動生成實體類展開,文中有非常詳細的介紹,需要的朋友可以參考下2021-06-06Redis 集成Spring的示例代碼(spring-data-redis)
本篇文章主要介紹了Redis 集成Spring的示例代碼(spring-data-redis) ,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09java使用FastJson解析Json數(shù)據(jù)
本篇文章主要介紹了java使用FastJson解析Json數(shù)據(jù),fastjson 是一個性能極好的用 Java 語言實現(xiàn)的 JSON 解析器和生成器,有興趣的可以了解一下。2017-02-02SpringBoot概述及在idea中創(chuàng)建方式
SpringBoot提供了一種快速使用Spring的方式,基于約定大于配置的思想,可以讓開發(fā)人員不必在配置與邏輯業(yè)務之間進行思維的切換,這篇文章主要介紹了SpringBoot概述及在idea中創(chuàng)建方式,需要的朋友可以參考下2022-09-09Java中ExecutorService和ThreadPoolExecutor運行原理
本文主要介紹了Java中ExecutorService和ThreadPoolExecutor運行原理,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08為IntelliJ IDEA配置JVM參數(shù)的兩種方法
在使用IntelliJ IDEA進行Java開發(fā)時,合理配置JVM參數(shù)對于優(yōu)化項目性能和資源管理至關重要,IntelliJ IDEA提供了兩種方便的方式來設置JVM參數(shù),本文將詳細介紹這兩種方法:通過工具欄編輯配置和通過服務編輯配置,需要的朋友可以參考下2024-12-12