Redis实现限流功能

Redis实现限流功能的优点:
  • 可以应用于分布式或者集群下
  • redis并发量大
Redis限流实现思路
使用redis中key的过期机制、key自增机制,
主类,可以在Filter或者HandlerInterceptor中定义,用于拦截请求
复制代码
@GetMapping(value = "/limitRate")
    public ServiceResult limitRate() {
        ServiceResult serviceResult = null;
        if(redisManage.getValue("LimitCount")!=null) {
            Integer countExist = (Integer) redisManage.getValue("LimitCount");
            Long expireTimes = redisManage.getExpire("LimitCount");
            if(expireTimes>-1) {
                if(countExist>10) {
                    serviceResult = new ServiceResult(-102,"LimitCount没秒超过10次访问,返回错误");
                    serviceResult.setData(countExist);
                    return serviceResult;
                }else {
                    String count = String.valueOf(countExist+1);
                    redisManage.increValue("LimitCount");
                    serviceResult = new ServiceResult(HttpResultEnum.SUCCESS);
                    serviceResult.setData(count);
                    return serviceResult;
                }
            }else {
                redisManage.delValue("LimitCount");
                redisManage.putValueExpireTimes("LimitCount",1,10L);
                serviceResult = new ServiceResult(100,"LimitCount超时,删除后,创建LimitCount=1");
                serviceResult.setData(1);
                return serviceResult;
            }
        }else {
            redisManage.putValueExpireTimes("LimitCount",1,10L);
            serviceResult = new ServiceResult(100,"LimitCount不存在,创建LimitCount=1");
            serviceResult.setData(1);
            return serviceResult;
        }
    }
复制代码

 

 
Redis实现类
复制代码
     
    /**
     * 自增
     * @param key
     * @return
     */
    public Integer increValue(String key) {
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        try{
            valueOperations.increment(key,1);
            LoggerUtil.info(logger, "key自增=" + valueOperations.get(key));
        }catch (Exception ex) {
            ex.printStackTrace();
        }
        return (Integer) valueOperations.get(key);
    }

    /**
     * 删除Redis中信息
     * @param key
     * @return
     */
    public void delValue(String key) {
        LoggerUtil.info(logger, "删除key=" + key);
        if (redisTemplate.hasKey(key)) {
            redisTemplate.delete(key);
        }
    }
    
    /**
     * 保存信息到Redis中,增加超时时间
     * @param key
     * @param value
     * @param expireTimes default 3600s
     */
    public void putValueExpireTimes(String key,String value,Long expireTimes) {
        LoggerUtil.info(logger, "保存key=" + key+";value=" + value);
        redisTemplate.opsForValue().set(key,value);
        if(expireTimes==null || expireTimes == 0L) {
            expireTimes = 3600L;
        }
        redisTemplate.expire(key, expireTimes, TimeUnit.SECONDS);
        LoggerUtil.info(logger, "设置超时时间:" + redisTemplate.getExpire(key, TimeUnit.SECONDS));
    }
复制代码

 

 
Redis连接池:
复制代码
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.database}")
    private int database;

    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.pool.max-active}")
    private int maxActive;

    /**
     * redis模板,存储关键字是字符串,值是Jdk序列化
     * @Description:
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
        template.afterPropertiesSet();
        return template;
    }

    private void setSerializer(StringRedisTemplate template) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
    }


    /**
     * redis连接的基础设置
     * @Description:
     * @return
     */
    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(host);
        factory.setPort(port);
        factory.setPassword(password);
        //存储的库
        factory.setDatabase(database);
        //设置连接超时时间
        factory.setTimeout(timeout);
        factory.setUsePool(true);
        factory.setPoolConfig(jedisPoolConfig());
        return factory;
    }

    /**
     * 连接池配置
     * @Description:
     * @return
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxTotal(maxActive);
        return jedisPoolConfig;
    }
复制代码

 

}
posted @   使用D  阅读(8168)  评论(0编辑  收藏  举报
编辑推荐:
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
点击右上角即可分享
微信分享提示