Redis的计数功能

Redis的学习专栏:http://t.csdnimg.cn/a8cvV

许多应用都会使用Redis作为计数的基本工具,可以实现快速计数、查询缓存的功能,同时数据也可以异步处理。例如:博客浏览,用户每查看一次,就会增加一次的访问量;手机验证码,一分钟之内只能发送一次!

普通的计数器,有很多bug,比如:访问量计数方式呢?阅读程度呢?总不可能一刷新就增加一次吧!

解决方法:在规定时间内一个用户,不能超过规定只能访问一次。而这种情况,我们可以先将数据存储在主存里,然后同步到数据库当中。

方法:

  1. 先初始化一下RedisTemplate,这个是操作redis的第三方库,我们先要对他初始化一下(重新序列化)
java 复制代码
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // 这个地方不可使用 json 序列化,如果使用的是ObjectRecord传输对象时,可能会有问题,会出现一个 java.lang.IllegalArgumentException: Value must not be null! 错误
        redisTemplate.setHashValueSerializer(RedisSerializer.string());
        return redisTemplate;
    }
}

2.访问

java 复制代码
 /**
     * 利用redis做计数器
     * 可以处理业务上面的的一些访问次数之类的
     * 例如:文章的点赞数,阅读量,允许有一点的延迟效果,先保存到redis中,然后在同步到数据库当中
     */
    @RequestMapping("hello")
    public void count() {
        /**
         * 判断是否到达次数
         */
        Boolean aBoolean = invokeExceededTimes("time_key2",1,3);
        if (aBoolean) {
            LOGGER.info("可以访问");
        }else {
            LOGGER.info("请求次数达标了");
        }
    }

    /**
     * 判断同一个key在规定时间内访问次数是否到达了最高值
     * @param key   键
     * @param days  时间
     * @param count 一定时间内的访问次数
     * @return
     */
    public Boolean invokeExceededTimes(String key, int days, int count) {

        LOGGER.info("key值:{}",key);
        // 判断在redis中是否有key值
        Boolean redisKey = stringRedisTemplate.hasKey(key);
        if (redisKey) {
            // 获取key所对应的value
            Integer hasKey =Integer.parseInt((String)stringRedisTemplate.opsForValue().get(key));
            if (hasKey >= count) {
                return false;
            }
            // 对value进行加1操作
            stringRedisTemplate.opsForValue().increment(key,1);
            return true;
        }else {
            // 如果没有key值,对他进行添加到redis中
            stringRedisTemplate.opsForValue().set(key,"1",days,TimeUnit.DAYS);
        }
        return true;
    }

我们设置每一个Redis当中的KEY值,如果KEY当中的值超过固定次数,则不会再自增了,而一旦过了存活时间之后就可以再次访问了。

RedisTemplate 常用方法

|------------------------------------------------------------------|----------------------------------------------------------------------|
| Boolean expire(K key, final long timeout, final TimeUnit unit) | 为指定的 key 指定缓存失效时间。时间一到 key 会被移除。key 不存在时,不影响 |
| Boolean expireAt(K key, final Date date) | 设置 key 失效日期。注意:如果 key 后续被重新设置值,比如 set key value,则 key 过期时间失效,需要重新设置。 |
| Long getExpire(K key) | 获取 key 的剩余过期时间。 -1 表示永久有效。-2 表示 key 不存在。 |
| Long getExpire(K key, final TimeUnit timeUnit) | 获取 key 的剩余过期时间,并换算成指定的时间单位 |
| Boolean hasKey(K key) | 判断 key 是否存在 |
| Boolean delete(K key) | 删除指定的 key |
| Long delete(Collection keys) | 删除多个 key |
| RedisSerializer<?> getDefaultSerializer() | 获取默认的序列化方式。RedisTemplate 是 JdkSerializationRedisSerializer; |
| Set keys(K pattern) | 获取整个库下符合指定正则的所有 key,如 keys(*) 获取所有 key |
| Boolean move(K key, final int dbIndex) | 将 key 从当前库移动目标库 dbIndex |
| ClusterOperations<K, V> opsForCluster() | 获取 ClusterOperations 用于操作集群 |
| GeoOperations<K, V> opsForGeo() | 获取 GeoOperations 用于操作地图 |
| redisTemplate.getConnectionFactory().getConnection().flushAll(); | //清空 redis 所有数据库(all databases)中的所有数据(all keys) |
| redisTemplate.getConnectionFactory().getConnection().flushDb(); | 清空 redis 当前连接的数据库(selected database)中的所有数据(all keys) |

还有很多很多方法,需要时再去找、使用。

相关推荐
不剪发的Tony老师19 分钟前
MySQL 9.5创新版发布,有哪些新功能?
数据库·mysql
布朗克1681 小时前
MySQL 及 SQL 注入详细说明
数据库·sql·mysql·1024程序员节
武子康1 小时前
Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例
java·数据库·分布式·sql·mongodb·性能优化·nosql
Austindatabases2 小时前
DBA 从“修电脑的” 到 上演一套 “数据治理” 大戏 --- 维护DBA生存空间,体现个体价值
数据库·dba
LB21122 小时前
Redis黑马点评 day01
数据库·redis·缓存
白小筠2 小时前
创建Django项目
数据库·django·sqlite
扑克中的黑桃A4 小时前
金仓多模数据库平替MongoDB的电子证照国产化实践——从2TB数据迁移到1600+并发支撑
数据库
计算机毕业设计小帅4 小时前
【2026计算机毕业设计】基于Django的社区婴幼儿预防接种系统
数据库·django·课程设计
友友马4 小时前
『 数据库 』MySQL复习 - 内置函数详解
数据库·mysql
互联网中的一颗神经元5 小时前
小白python入门 - 6. Python 分支结构——逻辑决策的核心机制
开发语言·数据库·python