转!利用redis-rua脚本对短信限流

转自:https://developer.aliyun.com/article/1165600

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Autowired
private RedisTemplate<String, Object> redisTemplate;
 
private static final String LIMIT_LUA = "local num = redis.call('incr', KEYS[1])\n" +
            "if num == 1 then\n" +
            "      redis.call('expire', KEYS[1], ARGV[1])\n" +
            "end\n" +
            "if num > tonumber(ARGV[2]) then\n" +
            "      return 0\n" +
            "end\n" +
            "return 1";
 
 /**
     * 推送频率限制,seconds内只允许limitNum次
     * @param key key
     * @param seconds 时间 秒
     * @param limitNum 限制次数
     * @return true:限制 false:不限制
     */
    public boolean checkIsLimited(String key, long seconds, long limitNum) {
        try {
            DefaultRedisScript redisScript = new DefaultRedisScript<>(LIMIT_LUA, Long.class);
            Long luaResult = (Long) redisTemplate.execute(redisScript, Collections.singletonList(key), seconds, limitNum);
            log.info("lua脚本执行结果luaResult={}", luaResult);
            return luaResult == 0;
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }
 
 
##业务代码:针对单个手机号下发限流
String busyKeyLua ="limit_single_phone:"+phone
boolean limitFlag = checkIsLimited(busyKeyLua, 10L, 2L);
if (limitFlag) {
log.warn("短信推送被限制,limitFlag={},busyKeyLua={}", limitFlag, busyKeyLua);
return new Result(400, "获取验证码过于频繁", null);
}

  

posted @   乌云de博客  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示