当前位置: 代码网 > it编程>数据库>Redis > Redis如何实现刷票过滤

Redis如何实现刷票过滤

2025年03月20日 Redis 我要评论
引言随着互联网的不断发展,网站或app的用户流量增加,也衍生出了一些恶意刷量等问题,给数据分析及运营带来极大的困难,出现的刷票问题更是造成了严重的经济损失,所以网站或app对恶意刷票进行过滤是十分必要

引言

随着互联网的不断发展,网站或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: 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开发应用

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: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数量
            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限制和过期时间设置外,还可以根据具体需求,对投票做更细粒度的控制,比如设置对投票用户的身份验证、对投票的时间和场次进行限制等等。

最后,需要注意的是,防范恶意刷票是非常重要的,但是过度的限制可能也会造成用户体验不佳,需要在保障数据安全的前提下,兼顾用户体验的优化。

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

参考资料:

  1. spring boot官方文档
  2. redis官方文档
  3. redisson官方文档
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com