SpringBoot整合Redis实现刷票过滤功能
引言
随着互联网的不断发展,网站或APP的用户流量增加,也衍生出了一些恶意刷量等问题,给数据分析及运营带来极大的困难,出现的刷票问题更是造成了严重的经济损失,所以网站或APP对恶意刷票进行过滤是十分必要的。Redis提供了很好的解决方案,其提供的内存存储和Key-Value的存储结构,能够高效地实现刷票过滤。
本文主要介绍如何使用SpringBoot和Redis实现刷票过滤,自定义同一IP每天刷票不得超过次数。
一、概述
本文主要分为以下几个模块:
1.开发环境
2.使用Redis存储数据
3.使用SpringBoot开发应用
4.实现同一IP每天刷票不得超过次数
二、技术选型
SpringBoot2.2.5.RELEASE
Spring5.2.4.RELEASE
JDK8
Redis
三、搭建开发环境
1.安装JDK8
2.安装Redis(版本不限,最好使用稳定版)
3.新建SpringBoot项目
使用IDEA新建SpringBoot项目
四、使用Redis存储数据
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: 63793. 在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开发应用
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数量
long voteCount = redisTemplate.opsForSet().size(voteKey);
// 判断是否超过投票限制
if(voteCount > 10){
return "您今天的投票数已经用尽!";
}
// 记录已经投票,设置过期时间为1天
redisTemplate.opsForValue().set(key,"已经投票", 1, TimeUnit.DAYS);
return "投票成功!";
}
}六、 实现同一IP每天刷票不得超过次数
1. 在VoteController的submit接口中实现同一IP每天刷票不得超过次数
每次投票时,先通过Redis查看是否已经投过票,如果已经投过票,则返回“您已经投过票了!”,否则将该IP添加到当天投票的Set中,再通过Redis查看当天投票的IP数量是否超过设定的阈值,如果超过则返回“您今天的投票数已经用尽!”,否则记录已经投票,并将该条记录设置为1天后过期。
上述逻辑可以采用Redis提供的Set和过期时间来完成,便捷高效。
2. 优化方案
上述实现在高并发情况下可能存在问题,比如多个用户同时投票,从而同时访问Redis,产生并发问题或者性能问题,为此可以通过Redis的分布式锁或者使用Redisson等第三方库来解决。
下面简单介绍一下使用Redisson来实现分布式锁。
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:6379c. 新建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数量
long voteCount = redisTemplate.opsForSet().size(voteKey);
// 判断是否超过投票限制
if (voteCount > 10) {
return "您今天的投票数已经用尽!";
}
// 记录已经投票,设置过期时间为1天
redisTemplate.opsForValue().set(key, "已经投票", 1, TimeUnit.DAYS);
return "投票成功!";
} finally {
lock.unlock();
}
}
}以上是使用Redisson实现分布式锁的思路及代码,从而在高并发情况下,避免了多个用户同时对Redis进行访问的并发问题。
七、总结
本文介绍了如何使用SpringBoot和Redis实现刷票过滤,自定义同一IP每天刷票不得超过次数的功能。
通过使用Redis的Set和过期时间,实现了同一IP每天刷票不得超过次数的限制,并且代码简单高效。
在高并发情况下,通过使用Redisson等库实现分布式锁,避免了多个用户同时访问Redis的性能问题。
在实际应用中,除了IP限制和过期时间设置外,还可以根据具体需求,对投票做更细粒度的控制,比如设置对投票用户的身份验证、对投票的时间和场次进行限制等等。
最后,需要注意的是,防范恶意刷票是非常重要的,但是过度的限制可能也会造成用户体验不佳,需要在保障数据安全的前提下,兼顾用户体验的优化。
本文主要介绍了如何使用SpringBoot和Redis实现刷票过滤,自定义同一IP每天刷票不得超过次数的功能。同时,还对高并发情况下可能存在的问题进行了分析,并提出了一些优化的方案。
到此这篇关于SpringBoot整合Redis实现刷票过滤功能的文章就介绍到这了,更多相关SpringBoot Redis刷票过滤内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Spring覆盖容器中Bean的注解如何实现@OverrideBean
文章介绍了在项目开发中如何通过偷梁换柱的方式重写Spring容器中的内置Bean,并指出了需要注意的两点:1. 对应的Bean应基于接口注入;2. 如果不是基于接口注入,可以使用同包名同类名的方式重写(可能存在潜在问题,不推荐),文章还强调了“基于接口编程”的好处2025-01-01
基于mybatis-plus timestamp返回为null问题的排除
这篇文章主要介绍了mybatis-plus timestamp返回为null问题的排除,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-08-08
解决java.lang.ClassCastException的java类型转换异常的问题
这篇文章主要介绍了解决java.lang.ClassCastException的java类型转换异常的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-09-09
MyBatis开发Dao层的两种方式实现(原始Dao层开发)
这篇文章主要介绍了MyBatis开发Dao层的两种方式实现(原始Dao层开发),并对数据库进行增删查改,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-12-12
SpringBoot配置文件方式,在线yml文件转properties
这篇文章主要介绍了SpringBoot配置文件方式,在线yml文件转properties,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-07-07
Idea2024创建Maven项目没有src文件夹的解决步骤
本文主要介绍了Idea2024创建Maven项目没有src文件夹,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2025-02-02


最新评论