springboot 项目实现分布式限流

项目需求:做到对业务号码实现限流,一分钟不能超过5条短信

实现方式:经过查询,可以使用cloud Gateway + redis去实现,但是在实际使用过程中,出现了jar不兼容问题;

最后采用自己逻辑实现的lua+java实现的分布式限流

网上有关于限流比较常见的楼桶法,具体可参考分布式限流漏桶法的实现,

我使用 了自己的逻辑实现,对redis使用一个定长队列,采取redis的lpush,lpop的方式去实现插入数据和去掉首部数据,队列里面存储的是时间戳,这样才能对长度和时间进行对比

基于java的实现,需要考虑分布式锁,这样才能保证并发的时候,对同一个key操作的时候,不会出现并发问题,可参考分布式锁的实现

很明显发现一个问题就是,对于一次限流操作,可能最多要操作5次redis,这样会增加redis的性能消耗,如果采用 lua脚本实现是不是更好呢?节省资源,原子性

lua脚本的好处及调用原则

lua脚本使用的优势及方法

java的实现

 private boolean hasCert(String key) {
        String result = redisService.setKeyValueWithTimeOut(LIMIT_LOCK.concat(key), "true", "NX", "PX", 100);
        logger.info("key:{}|result|{}", key, result);
        if ("OK".equals(result)) {
            long length = redisService.lLen(key);
            long timeStamp = System.currentTimeMillis();
            if (length == 0) {
                return handleNullList(key, timeStamp);
            }
            return handleNotNullList(key, length, timeStamp);
        }
        return true;
    }

        private boolean handleNullList(String key, long timeStamp) {
        redisService.rPush(key, String.valueOf(timeStamp));
        redisService.expire(key, time * 60);
        return true;
    }

    private boolean handleNotNullList(String key, long length, long timeStamp) {
        String times = String.valueOf(timeStamp);
        String data1 = redisService.lIndex(key, 0L);
        logger.info("data1|{}", data1);
        long interval = timeStamp - Long.parseLong(data1);
        logger.info("interval|{}", interval);
        if (length >= count) {
            if (interval > time * 60 * 1000) {
                redisService.rPush(key, times);
                redisService.lPop(key);
                redisService.expire(key, time * 60);
                return true;
            }
        } else {
            redisService.rPush(key, times);
            redisService.expire(key, time * 60);
            return true;
        }
        return false;
    }
}

具体代码可以换成lua脚本实现

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值