集群限流的一次坑坑坑

栏目: 数据库 · Redis · 发布时间: 5年前

内容简介:之前在一篇文章中提到过,因为业务的集群限流需求,在每次请求都需要拿到当前的日期,不过精确到天即可。上次给出的解决方案是,因为Calendar的性能问题,选择更加直接粗暴的方式,就是下面这个。通过当前的时间戳(毫秒级别),除以一天的毫秒数,得到的结果就是从1970 到今天经历过的天数。最近业务在使用限流功能时,需要实现限制接口每天调用1w次。

之前在一篇文章中提到过,因为业务的集群限流需求,在每次请求都需要拿到当前的日期,不过精确到天即可。上次给出的解决方案是,因为Calendar的性能问题,选择更加直接粗暴的方式,就是下面这个。

private static final int DAY_MILLIS = 24 * 60 * 60 * 1000;
long day = System.currentTimeMillis() / DAY_MILLIS;

通过当前的时间戳(毫秒级别),除以一天的毫秒数,得到的结果就是从1970 到今天经历过的天数。

最近业务在使用限流功能时,需要实现限制接口每天调用1w次。

只是,第一个版本的实现逻辑是这样的,如果第一个请求是早上8点过来的,那么会在 redis 创建一个对应的key,并设置24小时过期。所以从今天早上8点到明天早上8点,只能调用1w次,多余的就拒绝,所以每天限制的时间段可能是不一样的。

业务提出了新需求:必须按照0点到第二天0的时间段进行限制。

对于这个需求,我表示会心一笑,上述的粗暴方案不是正好满足么,三下五除二,就给加上了这个功能。

if (timeUnit == TimeUnit.DAYS) {
    key = ruleId + TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis());
}

如果业务配置的限流周期是天,那么就在原始id上再加上当前的天数当前redis的key,那么每天的key都是不一样的,新的一天,都会有一个新的key,如此的美好。

业务使用改进后的版本上线了2天,甩过来一个监控页面,开始diss我们了,为什么昨天触发了限流,今天凌晨2点多还在限流。看着埋点数据,发现这个锅是甩不掉了,只能开始翻代码,无果。

后来通过redis的埋点数据,发现2点多操作的redis key上还是昨天的天数。很奇怪,有木有?明明已经2点了,怎么还是昨天的天数,我已经开始怀疑服务器的时间是不是有问题,居然鬼使神差的让业务去验证服务器的时间,结果是我被打脸了。

到最后,我才把关注点放在了 System.currentTimeMillis() 这个返回值上,这个返回的时间戳是从1970开始到现在格林威治时间的时间戳,而北京时间比格林威治整整快了8个小时。

所以真相是,通过暴力方案返回的天数,在北京时间早上8点之前都算是之前一天,过了8点,才算是新的一天,才会使用新的redis key进行计数。

继续修复,继续发版,下次在使用这种暴力方案时,考虑一下时区问题。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

视觉SLAM十四讲

视觉SLAM十四讲

高翔、张涛、等 / 电子工业出版社 / 2017-3 / 75

《视觉SLAM十四讲:从理论到实践》系统介绍了视觉SLAM(同时定位与地图构建)所需的基本知识与核心算法,既包括数学理论基础,如三维空间的刚体运动、非线性优化,又包括计算机视觉的算法实现,例如多视图几何、回环检测等。此外,还提供了大量的实例代码供读者学习研究,从而更深入地掌握这些内容。 《视觉SLAM十四讲:从理论到实践》可以作为对SLAM 感兴趣的研究人员的入门自学材料,也可以作为SLAM......一起来看看 《视觉SLAM十四讲》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具