场景:xxx时间内只能yyy次

在redis里维护一个数字类型的k-v,key的生成策略与频控的维度有关,比如是用户级的频控,那么key就是一个userId;如果是总频控,那么key就是一个string常量。
key的过期时间就是频控的时间间隔,在创建key的时候设置过期时间。过频控时,需要将key的计数值自增。

关于自增的时机:

第一种:先get再incr。
第二种:先incr再get。

这两种都可以,看具体的场景。
如果过了频控,后续的业务操作还有其他条件,不一定成功,这种需要用方案一。比如发奖励,频控只是一种条件,频控没问题,还需要判断其他条件,比如幂等,预算等等,如果先incr,但是后续业务操作因为其他原因失败了,也消耗了频控的计数。对于这类型的场景,需要采用方案一,即先get判断,操作成功后再incr。
如果后续业务操作没有其他条件,可以采用方案二。比如api接口的频控,只要有请求过来,就要消耗一次频控计数。

优点:实现简单,可以满足一般的场景
缺点:
1.由于incr和get不是原子的,所以频控可能不准。如果是先incr,那么可能会多拦掉一些请求。如果是先get,那么可能会多放过一些请求;
2.只在时间段内满足,比如要求是5分钟内不超过10次。那么相邻的两个5分钟其实是两个key,各管各的频控。比如在第4分钟时,访问了9次,ok。紧接着在第六分钟时也访问了9次,也ok。在各自的时间段内,满足频控要求的,但是从业务上看,4-9分钟这一段时间内,访问了9+9=18次,是不满足频控要求的。这属于方案本身的限制。