Redis计数器实现并发控制,接口限流

本文通过一个短信发送并发请求的问题,阐述了接口防刷和限流的重要性。利用Redis的incr命令,实现了一分钟内同一号码只能获取一次短信验证码的限制,以此避免服务器高负载和资源浪费。详细介绍了设计思路和具体的代码实现,包括Jedis工具类方法、接口限流逻辑和实现类。
摘要由CSDN通过智能技术生成

       例子:短信发送的并发请求问题,是需要限制一个号码一分钟内只能获取一次随机码,一般的接口开发刷新一次接口链接就会发送一次短信,当有大用户量并发时会造成服务器高负载,短信资源的极大浪费,因此有必要做接口的防刷和限流。实现方式可以在前端设定时间,也可以在接口处用缓存做接口限流进行实现。

1.使用Redis incr解决问题

       Redis incr 可以实现原子性的递增,可应用于高并发的秒杀活动、分布式序列号生成等场景。这里我使用它来计数实现一分钟内只接受一次请求。

 2.设计思路

      实现逻辑也很简单:我们在接到短信发送请求后,使用Redis的incr设置一个递增KEY(KEY由固定字符串+手机号码组成),并判断该KEY的数值,如果等于1,说明是第一个请求,我们将该KEY值有效期设置为一分钟;如果该KEY的数值大于1,说明是1分钟内的多次请求,这时我们直接返回短信获取频繁异常。

 3.代码实现

3.1 Jedis工具类用到的方法

	/**
	    * 获取缓存自增值
	 * @param key
	 * @return
	 */
	public static long increment(String key) {
		long value = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			value = jedis.incr(key);
			logger.debug("get {} = {}", key, value);
		} catch (Exception e) {
			logger.warn("get {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}
	
	/**
	    *   设置某个缓存key的超时时间
	 * @param key
	 * @param seconds
	 */
	public static void expire(String key,int seconds) {
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				jedis.expire(key, seconds);
			}
		} catch (Exception e) {
			logger.warn("get {} = {}", key, e);
		} finally {
			returnResource(jedis);
		}
	}

3.2 接口限流部分

            //接口限流
            String redisKey = "SMS_CODE_" + mobile;      //缓存键值
            long count = JedisUtils.increment(redisKey);  //获取发送短信的次数
            if(count == 1) {
            	//设置有效期一分钟
            	JedisUtils.expire(redisKey, 60);   
            }else if(count >1) {
            	rr.setState(ResponseResult.STATE_ERROR);
                rr.setMessage("请求太频繁,每分钟只能发送一次短信");
            	LOG.debug("请求太频繁,每分钟只能发送一次短信");
            	return rr;
            }
            
            //短信发送逻辑

3.3 具体实现类


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇潇雨歇_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值