• 当遇到需求,在规定时间,用户的访问量不能超过规定次数的时候就可以用redis中的计数器来实现了
  • 又可以使用这个技术用来做限流(使用用户的ip作为key,用户访问一次,就加1,如果超过次数就返回false)
  • 可以处理业务上面的的一些访问次数之类的,例如:文章的点赞数,阅读量,允许有一点的延迟效果,先保存到redis中,然后在同步到数据库当中
  • 首先我们先初始化一下RedisTemplate,这个是操作redis的第三方库,我们先要对他初始化一下(重新序列化)
  • 先把StringRedisTemplate注入进来,这里有人会用RedisTemplate可能会报错,可能是序列化的问题,私下百度一下就行了
    @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;
    }
}
  • 然后我们就可以用@Autowired进行注入到spring容器中使用了,这里我将方法都放在一个类中,用作与测试的
 /**
     * 利用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;
    }
  • 这里面有用到这两个方法,关注一下
   // 对value进行加1操作
            stringRedisTemplate.opsForValue().increment(key,1);
     // 判断在redis中是否有key值
        Boolean redisKey = stringRedisTemplate.hasKey(key);
  • 最后我测试的是同一个key只能访问三次,当然根据业务需求来就行了,我这里只是一个测试
    在这里插入图片描述
  • 就到这里了,后面会分享更多的关于redis的操作
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐