最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis如何實(shí)現(xiàn)刷票過(guò)濾

 更新時(shí)間:2025年03月20日 15:50:21   作者:沙漠真有魚(yú)  
這篇文章主要介紹了Redis如何實(shí)現(xiàn)刷票過(guò)濾問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

引言

隨著互聯(lián)網(wǎng)的不斷發(fā)展,網(wǎng)站或APP的用戶(hù)流量增加,也衍生出了一些惡意刷量等問(wèn)題,給數(shù)據(jù)分析及運(yùn)營(yíng)帶來(lái)極大的困難,出現(xiàn)的刷票問(wèn)題更是造成了嚴(yán)重的經(jīng)濟(jì)損失,所以網(wǎng)站或APP對(duì)惡意刷票進(jìn)行過(guò)濾是十分必要的。

Redis提供了很好的解決方案,其提供的內(nèi)存存儲(chǔ)和Key-Value的存儲(chǔ)結(jié)構(gòu),能夠高效地實(shí)現(xiàn)刷票過(guò)濾。

本文主要介紹如何使用SpringBoot和Redis實(shí)現(xiàn)刷票過(guò)濾,自定義同一IP每天刷票不得超過(guò)次數(shù)。

一、概述

本文主要分為以下幾個(gè)模塊:

  • 1.開(kāi)發(fā)環(huán)境
  • 2.使用Redis存儲(chǔ)數(shù)據(jù)
  • 3.使用SpringBoot開(kāi)發(fā)應(yīng)用
  • 4.實(shí)現(xiàn)同一IP每天刷票不得超過(guò)次數(shù)

二、技術(shù)選型

  • SpringBoot2.2.5.RELEASE
  • Spring5.2.4.RELEASE
  • JDK8
  • Redis

三、搭建開(kāi)發(fā)環(huán)境

  • 1.安裝JDK8
  • 2.安裝Redis(版本不限,最好使用穩(wěn)定版)
  • 3.新建SpringBoot項(xiàng)目

使用IDEA新建SpringBoot項(xiàng)目

四、使用Redis存儲(chǔ)數(shù)據(jù)

1. 在pom.xml中加入Redis依賴(lài)

<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開(kāi)發(fā)應(yīng)用

1.在pom.xml中加入SpringBoot依賴(lài)

<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;

        // 先判斷是否已經(jīng)投票,如果已經(jīng)投票,則返回
        if(redisTemplate.opsForValue().get(key) != null){
            return "您已經(jīng)投過(guò)票了!";
        }

        // 獲取當(dāng)天的日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String date = sdf.format(new Date());

        // 拼接當(dāng)天投票的key
        String voteKey = "vote:" + date;

        // 將IP添加到Set中,記錄當(dāng)天所有投票的IP
        redisTemplate.opsForSet().add(voteKey,ip);

        // 獲取當(dāng)天已經(jīng)投票的IP數(shù)量
        long voteCount = redisTemplate.opsForSet().size(voteKey);

        // 判斷是否超過(guò)投票限制
        if(voteCount > 10){
            return "您今天的投票數(shù)已經(jīng)用盡!";
        }

        // 記錄已經(jīng)投票,設(shè)置過(guò)期時(shí)間為1天
        redisTemplate.opsForValue().set(key,"已經(jīng)投票", 1, TimeUnit.DAYS);

        return "投票成功!";
    }
}

五、 實(shí)現(xiàn)同一IP每天刷票不得超過(guò)次數(shù)

1. 在VoteController的submit接口中實(shí)現(xiàn)同一IP每天刷票不得超過(guò)次數(shù)

每次投票時(shí),先通過(guò)Redis查看是否已經(jīng)投過(guò)票,如果已經(jīng)投過(guò)票,則返回“您已經(jīng)投過(guò)票了!”,否則將該IP添加到當(dāng)天投票的Set中,再通過(guò)Redis查看當(dāng)天投票的IP數(shù)量是否超過(guò)設(shè)定的閾值,如果超過(guò)則返回“您今天的投票數(shù)已經(jīng)用盡!”,否則記錄已經(jīng)投票,并將該條記錄設(shè)置為1天后過(guò)期。

上述邏輯可以采用Redis提供的Set和過(guò)期時(shí)間來(lái)完成,便捷高效。

2. 優(yōu)化方案

上述實(shí)現(xiàn)在高并發(fā)情況下可能存在問(wèn)題,比如多個(gè)用戶(hù)同時(shí)投票,從而同時(shí)訪問(wèn)Redis,產(chǎn)生并發(fā)問(wèn)題或者性能問(wèn)題,為此可以通過(guò)Redis的分布式鎖或者使用Redisson等第三方庫(kù)來(lái)解決。

下面簡(jiǎn)單介紹一下使用Redisson來(lái)實(shí)現(xiàn)分布式鎖。

  • a. 在pom.xml中加入Redisson依賴(lài)
<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 {
            // 先判斷是否已經(jīng)投票,如果已經(jīng)投票,則返回
            if (redisTemplate.opsForValue().get(key) != null) {
                return "您已經(jīng)投過(guò)票了!";
            }

            // 獲取當(dāng)天的日期
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String date = sdf.format(new Date());

            // 拼接當(dāng)天投票的key
            String voteKey = "vote:" + date;

            // 將IP添加到Set中,記錄當(dāng)天所有投票的IP
            redisTemplate.opsForSet().add(voteKey, ip);

            // 獲取當(dāng)天已經(jīng)投票的IP數(shù)量
            long voteCount = redisTemplate.opsForSet().size(voteKey);

            // 判斷是否超過(guò)投票限制
            if (voteCount > 10) {
                return "您今天的投票數(shù)已經(jīng)用盡!";
            }

            // 記錄已經(jīng)投票,設(shè)置過(guò)期時(shí)間為1天
            redisTemplate.opsForValue().set(key, "已經(jīng)投票", 1, TimeUnit.DAYS);

            return "投票成功!";
        } finally {
            lock.unlock();
        }
    }
}

以上是使用Redisson實(shí)現(xiàn)分布式鎖的思路及代碼,從而在高并發(fā)情況下,避免了多個(gè)用戶(hù)同時(shí)對(duì)Redis進(jìn)行訪問(wèn)的并發(fā)問(wèn)題。

六、總結(jié)

本文介紹了如何使用SpringBoot和Redis實(shí)現(xiàn)刷票過(guò)濾,自定義同一IP每天刷票不得超過(guò)次數(shù)的功能。

通過(guò)使用Redis的Set和過(guò)期時(shí)間,實(shí)現(xiàn)了同一IP每天刷票不得超過(guò)次數(shù)的限制,并且代碼簡(jiǎn)單高效。

在高并發(fā)情況下,通過(guò)使用Redisson等庫(kù)實(shí)現(xiàn)分布式鎖,避免了多個(gè)用戶(hù)同時(shí)訪問(wèn)Redis的性能問(wèn)題。

在實(shí)際應(yīng)用中,除了IP限制和過(guò)期時(shí)間設(shè)置外,還可以根據(jù)具體需求,對(duì)投票做更細(xì)粒度的控制,比如設(shè)置對(duì)投票用戶(hù)的身份驗(yàn)證、對(duì)投票的時(shí)間和場(chǎng)次進(jìn)行限制等等。

最后,需要注意的是,防范惡意刷票是非常重要的,但是過(guò)度的限制可能也會(huì)造成用戶(hù)體驗(yàn)不佳,需要在保障數(shù)據(jù)安全的前提下,兼顧用戶(hù)體驗(yàn)的優(yōu)化。

這些僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

參考資料:

  1. Spring Boot官方文檔
  2. Redis官方文檔
  3. Redisson官方文檔

相關(guān)文章

  • Redis設(shè)置密碼保護(hù)的實(shí)例講解

    Redis設(shè)置密碼保護(hù)的實(shí)例講解

    今天小編就為大家分享一篇Redis設(shè)置密碼保護(hù)的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Redis高并發(fā)分布鎖的示例

    Redis高并發(fā)分布鎖的示例

    在分布式系統(tǒng)中,實(shí)現(xiàn)分布式鎖是一項(xiàng)常見(jiàn)的需求,本文主要介紹了Redis高并發(fā)分布鎖的示例 ,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • redis-cli命令行工具的使用小結(jié)

    redis-cli命令行工具的使用小結(jié)

    redis-cli是Redis的命令行客戶(hù)端,支持多種參數(shù)用于連接、操作和管理Redis數(shù)據(jù)庫(kù),本文給大家介紹redis-cli命令行工具的使用小結(jié),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 帶你輕松掌握Redis分布式鎖

    帶你輕松掌握Redis分布式鎖

    這篇文章主要介紹了帶你輕松掌握Redis分布式鎖,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 一文詳解redis高可用Sentinel?

    一文詳解redis高可用Sentinel?

    本文主要介紹了redis高可用Sentinel的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Redis Stat的安裝指南

    Redis Stat的安裝指南

    這篇文章主要介紹了Redis Stat的安裝指南的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • 詳解redis分布式鎖的這些坑

    詳解redis分布式鎖的這些坑

    在很多互聯(lián)網(wǎng)產(chǎn)品應(yīng)用中,有些場(chǎng)景需要加鎖處理,比如:秒殺,全局遞增ID等等。大部分的解決方案是基于DB實(shí)現(xiàn)的,Redis為單進(jìn)程單線程模式,采用隊(duì)列模式將并發(fā)訪問(wèn)變成串行訪問(wèn),且多客戶(hù)端對(duì)Redis的連接并不存在競(jìng)爭(zhēng)關(guān)系。
    2021-05-05
  • Redis中scan命令的深入講解

    Redis中scan命令的深入講解

    這篇文章主要給大家介紹了關(guān)于Redis中scan命令的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • 如何打造redis緩存組件

    如何打造redis緩存組件

    文章介紹了如何使用熱插拔AOP、反射、Redis自定義注解和SpringEL表達(dá)式來(lái)打造一個(gè)優(yōu)雅的Redis緩存組件,通過(guò)這種方式,可以重構(gòu)和簡(jiǎn)化緩存代碼,并提供了Redis配置和自定義注解的詳細(xì)說(shuō)明,文章還包含了AOP測(cè)試的總結(jié),并鼓勵(lì)讀者參考和支持
    2024-12-12
  • Redis數(shù)據(jù)庫(kù)分布式設(shè)計(jì)方案介紹

    Redis數(shù)據(jù)庫(kù)分布式設(shè)計(jì)方案介紹

    大家好,本篇文章主要講的是Redis數(shù)據(jù)庫(kù)分布式設(shè)計(jì)方案介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01

最新評(píng)論

多伦县| 景谷| 石城县| 吴旗县| 海阳市| 铜鼓县| 海城市| 左云县| 精河县| 乌恰县| 绥德县| 通山县| 卢龙县| 云林县| 武定县| 太湖县| 虞城县| 孙吴县| 华坪县| 内黄县| 阜阳市| 札达县| 资兴市| 吐鲁番市| 屏东县| 峡江县| 闻喜县| 清新县| 云梦县| 咸阳市| 金乡县| 顺义区| 遂川县| 石棉县| 鲜城| 潼南县| 怀安县| 扬中市| 鱼台县| 茂名市| 甘德县|