RateLimiter深度使用下

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 《基础》

使用RateLimiter完成简单的大流量限流,抢购秒杀限流。 RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。 通常可应用于抢购限流防止冲垮系统;限制某接口、服务单位时间内的访问量,譬如一些第三方服务会对用户访问量进行限制;限制网速,单位时间内只允许上传下载多少字节等。 下面来看一些简单的实践demo,需要先引入guava的maven依赖。 Demo1.有很多任务,但希望每秒不超过N个

/** 
     *  
     * 有很多个任务,但希望每秒不超过X个,可用此类 
     */  
    public class Demo1 {  
        public static void main(String[] args) {  
            //0.5代表一秒最多多少个  
            RateLimiter rateLimiter = RateLimiter.create(0.5);  
            List<Runnable> tasks = new ArrayList<Runnable>();  
            for (int i = 0; i < 10; i++) {  
                tasks.add(new UserRequest(i));  
            }  
            ExecutorService threadPool = Executors.newCachedThreadPool();  
            for (Runnable runnable : tasks) {  
                System.out.println("等待时间:" + rateLimiter.acquire());  
                threadPool.execute(runnable);  
            }  
        }  
        private static class UserRequest implements Runnable {  
            private int id;  
            public UserRequest(int id) {  
                this.id = id;  
            }  
            public void run() {  
                System.out.println(id);  
            }  
    }  
}点击复制代码复制出错复制成功

Demo2.抢购场景限流 如我们预估数据库能承受并发10,超过了可能会造成故障,我们就可以对该请求接口进行限流。

@RestController  
    public class IndexController {  
        @Resource(name = "db")  
        private GoodInfoService goodInfoService;  
        RateLimiter rateLimiter = RateLimiter.create(10);  
        @RequestMapping("/miaosha")  
        public Object miaosha(int count, String code) {  
            System.out.println("等待时间" + rateLimiter.acquire());  
            if (goodInfoService.update(code, count) > 0) {  
                return "购买成功";  
            }  
            return "购买失败";  
        }  
        @RequestMapping("/add")  
        public Object add() {  
            for (int i = 0; i < 100; i++) {  
                GoodInfo goodInfo = new GoodInfo();  
                goodInfo.setCode("iphone" + i);  
                goodInfo.setAmount(100);  
                goodInfoService.add(goodInfo);  
            }  
            return "添加成功";  
        }  
    }  点击复制代码复制出错复制成功

Demo3.抢购场景降级

/** 
     * tryAcquire(long timeout, TimeUnit unit) 
     * 从RateLimiter 获取许可如果该许可可以在不超过timeout的时间内获取得到的话, 
     * 或者如果无法在timeout 过期之前获取得到许可的话,那么立即返回false(无需等待) 
     */  
    @RequestMapping("/buy")  
    public Object miao(int count, String code) {  
        //判断能否在1秒内得到令牌,如果不能则立即返回false,不会阻塞程序  
        if (!rateLimiter.tryAcquire(1000, TimeUnit.MILLISECONDS)) {  
            System.out.println("短期无法获取令牌,真不幸,排队也瞎排");  
            return "失败";  
        }  
        if (goodInfoService.update(code, count) > 0) {  
            System.out.println("购买成功");  
            return "成功";  
        }  
        System.out.println("数据不足,失败");  
        return "失败";  
    }  点击复制代码复制出错复制成功

rediscell的使用

Redis 4.0 版本中提供的 Redis-Cell 模块,该模块使用的是漏斗算法,并且提供了原子的限流指令,而且依靠 Redis 这个天生的分布式程序就可以实现比较完美的限流了。Redis-Cell 实现限流的方法也很简单,只需要使用一条指令 cl.throttle 即可,使用示例如下:

> cl.throttle mylimit 15 30 60
1)(integer)0 # 0 表示获取成功,1 表示拒绝
2)(integer)15 # 漏斗容量
3)(integer)14 # 漏斗剩余容量
4)(integer)-1 # 被拒绝之后,多长时间之后再试(单位:秒)-1 表示无需重试
5)(integer)2 # 多久之后漏斗完全空出来
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
安全 算法 应用服务中间件
互联网并发与安全系列教程(03) - RateLimiter使用AOP方式实现限流
互联网并发与安全系列教程(03) - RateLimiter使用AOP方式实现限流
86 0
|
4月前
|
监控 算法 Java
详解 Java 限流接口实现问题之避免令牌桶限流算法可能导致的过载问题如何解决
详解 Java 限流接口实现问题之避免令牌桶限流算法可能导致的过载问题如何解决
|
4月前
|
算法 Java 调度
高并发架构设计三大利器:缓存、限流和降级问题之使用Java代码实现令牌桶算法问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之使用Java代码实现令牌桶算法问题如何解决
|
6月前
|
存储 算法 Java
【令牌桶算法与漏桶算法】
【令牌桶算法与漏桶算法】
149 0
|
6月前
|
算法 Java Spring
用 Spring Boot 实现秒杀系统的流量控制:计数器算法与令牌桶算法
用 Spring Boot 实现秒杀系统的流量控制:计数器算法与令牌桶算法
124 0
|
算法
SpingCloud 限流的令牌桶算法和漏桶算法
SpingCloud 限流的令牌桶算法和漏桶算法
151 1
|
存储 算法 NoSQL
RateLimiter源码分析
RateLimiter源码分析
156 0
RateLimiter源码分析
常用限流算法的Java实现
主要内容为滑动日志,令牌桶,漏桶三种限流算法的Java实现 获取连接许可的接口
|
存储 算法 Java
超详细的Guava RateLimiter限流原理解析
限流是保护高并发系统的三把利器之一,另外两个是缓存和降级。限流在很多场景中用来限制并发和请求量,比如说秒杀抢购,保护自身系统和下游系统不被巨型流量冲垮等。
|
算法 前端开发 Java
实战限流(guava的RateLimiter)
guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,本文实战一下RateLimiter的用法
1260 0
实战限流(guava的RateLimiter)