使用 redis 做限流
背景
事情是这样来的,最近2天 tool.lu 的 uv 并没有大幅的增长,但是 pv 的涨幅却很大,造成服务器的 load 一度超过了 20,想必是被攻击,做过php-fpm的优化,收效甚微。故想到了限流
限流的使用场景
- API的调用次数限制
- 防止频繁刷新
- etc...
想法和实现
其实我是参考了下面这篇文章的实现,至于为什么要这么做,我的考虑跟他文章中提到的是一致的,可以查看原文
原文中提供了大段的文字说明,于是我根据他的说明,做了一幅图,仅供参考:
这里需要说明的是,原文中使用的是redis中的hash,但是hash对其中的每个元素没有单独的失效时间,所以使用原文的方法是有bug的;
具体情况请看 issue
这里改用string类型来存储就可以啦!注意将 bucketSpan
和 expire
设置为同一个值
优化
使用string类型来存储,可以发现key的空间占用比较多,更耗内存了;我们可以压缩一下key来实现节省内存的目的。
实际应用
- tool.lu web限流 (php实现版本)
- coderunner sandbox限流 (go实现版本)