使用Redis计数器实现控制某某API调用的限制

最近突然接到个需求,因为项目中使用的谷歌地图的三方API每调用一次需要刀,所以客户怕使用过量,想要加个可调节的次数控制具体到当前每小时和每天的数量限制,想到得解决方案就是使用redis当计数器在数据库配好次数规则,实现起来也非常简单

1.设置好计数器的key和缓存,这里为了方便就直接用redisson自带的功能了

//小时调用次数
RAtomicLong counterHour  = redisson.getAtomicLong(RedisKeys.GOOGLE_MAP_HOUR_KEY);
// 获取一小时内的接口调用次数
long hourCount = counterHour.get();

2.规则校验这里就是读库校验规则然后通过就是加一

SysConfig configHour = sysConfigService.selectConfigById(ConfigKeys.GOOGLE_MAP_HOUR_APIKEY);
if (Long.parseLong(configHour.getConfigValue())<=hourCount){
    return Result.success(false);
}
counterHour.incrementAndGet();

3.然后就是更新缓存时间了,这里有个细节,需要计算出当前的时间到下个整点时间的秒数,而不是重新设置一小时,不然这样这个key就变成永久的了每天的key就不会生效,每天和每小时的逻辑差不多,就不写出来了

setNextHourExpiration(counterHour,1);
private static void setNextHourExpiration(RAtomicLong counter,Integer type) {
    if (type == 1){
        LocalDateTime now = LocalDateTime.now();
        LocalTime nextHour = LocalTime.of(now.getHour() + 1, 0);
        LocalDateTime nextHourDateTime = now.with(nextHour);
        Duration duration = Duration.between(now, nextHourDateTime);
        long expireTime = duration.getSeconds();
        counter.expire(expireTime, TimeUnit.SECONDS);
    }
    if (type == 2){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime nextDay = now.plus(1, ChronoUnit.DAYS).with(LocalTime.MIN);
        Duration duration = Duration.between(now, nextDay);
        long expireTime = duration.getSeconds();
        counter.expire(expireTime, TimeUnit.SECONDS);
    }
}

前端调用API前都要调用这个接口获取许可才能调用否则就是拒绝

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值