rateLimiter令牌桶限流算法
RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。
通常可应用于抢购限流防止冲垮系统;限制某接口、服务单位时间内的访问量,譬如一些第三方服务会对用户访问量进行限制;限制网速,单位时间内只允许上传下载多少字节等。
下面来看一些简单的实践,需要先引入guava的maven依赖。
一 有很多任务,但希望每秒不超过N个
- import com.google.common.util.concurrent.RateLimiter;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- /**
- * Created by wuwf on 17/7/11.
- * 有很多个任务,但希望每秒不超过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);
- }
- }
- }
该例子是多个线程依次执行,限制每2秒最多执行一个。运行看结果
我们限制了2秒放行一个,可以看到第一个是直接执行了,后面的每2秒会放行一个。
二 抢购场景限流
- package com.tianyalei.controller;
- import com.google.common.util.concurrent.RateLimiter;
- import com.tianyalei.model.GoodInfo;
- import com.tianyalei.service.GoodInfoService;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import javax.annotation.Resource;
- /**
- * Created by wuwf on 17/7/11.
- */
- @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 "添加成功";
- }
- }
这个是接着之前的文章(秒杀系统db,http://blog.csdn.net/tianyaleixiaowu/article/details/74389273)加了个Controller
三 抢购场景降级
- /**
- * 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 "失败";
- }
在不看执行结果的情况下,我们可以先分析一下,一秒出10个令牌,0.1秒出一个,100个请求进来,假如100个是同时到达,那么最终只能成交10个,90个都会因为超时而失败。事实上,并不会完全同时到达,必然会出现在0.1秒后到达的,就会被归入下一个周期。这是一个挺复杂的数学问题,每一个请求都会被计算未来可能获取到令牌的概率。
rateLimiter令牌桶限流算法相关推荐
- 微服务限流及熔断一:四种限流算法(计数器算法、滑动窗口算法、令牌限流算法、漏桶限流算法)
引言 本篇内容根据<spring cloud alibaba 微服务原理与实战>中内容摘取,希望和大家分享限流的思想,本篇不涉及代码层面的实现. 限流的目的 目的:通过限制并发访问数或者限 ...
- 【秒杀系统】零基础上手秒杀系统(二):令牌桶限流 + 再谈超卖
前言 本文是秒杀系统的第二篇,通过实际代码讲解,帮助你快速的了解秒杀系统的关键点,上手实际项目. 本篇主要讲解接口限流措施,接口限流其实定义也非常广,接口限流本身也是系统安全防护的一种措施,暂时列举这 ...
- 什么是限流?为什么会限流呢?常见的限流算法【固定窗口限流、滑动窗口限流、漏桶限流、令牌桶限流】是什么呢?
什么是限流?为什么会限流呢?常见的限流算法[固定窗口限流.滑动窗口限流.漏桶限流.令牌桶限流]是什么呢? 什么是限流? 为什么会限流? 1. 固定窗口限流算法 1.1 什么是固定窗口限流算法 1.2 ...
- ASP.NET Core中使用令牌桶限流
在限流时一般会限制每秒或每分钟的请求数,简单点一般会采用计数器算法,这种算法实现相对简单,也很高效,但是无法应对瞬时的突发流量. 比如限流每秒100次请求,绝大多数的时间里都不会超过这个数,但是偶尔某 ...
- Jedis使用lua脚本完成令牌桶限流
Jedis使用lua脚本完成令牌桶限流 文章目录 Jedis使用lua脚本完成令牌桶限流 一.lua脚本的简单语法 二.令牌桶限流 1. 构思 2. 实现 三.Jemeter压测工具测试 一.lua脚 ...
- 可能要用心学高并发核心编程,限流原理与实战,分布式令牌桶限流
实战:分布式令牌桶限流 本节介绍的分布式令牌桶限流通过Lua+Java结合完成,首先在Lua脚本中完成限流的计算,然后在Java代码中进行组织和调用. 分布式令牌桶限流Lua脚本 分布式令牌桶限流Lu ...
- 十三水算法php_基于PHP+Redis令牌桶限流
一 .场景描述 在开发接口服务器的过程中,为了防止客户端对于接口的滥用,保护服务器的资源, 通常来说我们会对于服务器上的各种接口进行调用次数的限制.比如对于某个 用户,他在一个时间段(interval ...
- 基于Redis和 Lua 实现分布式令牌桶限流
rpc-tech-stack 系列的实践文章 ~ 本文属于限流话题. 限流是一个很大的话题,准备把其中的所有限流器都实现一遍,以此也算全都写过了,到时候再用也不至于会心虚,毕竟真实写完成过.本文主要讲 ...
- 令牌桶限流之redis-cell的安装,使用,详解
简言 1. redis使用有序集合zset也能实现简单的限流,但是只能处理几十,几百的量级,因为zset需要记录每一条信息,很占据空间.要想处理更大数量级的限流,必须使用其他方法 2. 通常的限流算法 ...
最新文章
- Ora_Excel 碉堡了
- flask需求文件requirements.txt的创建及使用
- 武汉大学计算机学院c404,985录取名单(武大)!武大不歧视!80分政治复习路线图!最新调剂信息!...
- 性能测试:基础(4)
- oracle设置禁用外键,oracle禁用表外键
- 《Java就业培训教程》_张孝祥_书内源码_04
- Java程序设计基础------Java基础
- 武汉市房价数据挖掘与可视化分析(Python)
- 【Multisim仿真+报告+演示视频】数电课设五人表决器Multisim仿真设计【全套资料】资源编号:YM5-V1.0.1-五人表决器
- 无线蓝牙耳机选购小知识,2020新款上市五大高人气蓝牙耳机推荐
- word流程图怎么使箭头对齐_word里流程图的直角箭头怎么画
- python创建excel并冻结首行
- windows下tomcat7日志配置
- java计算机毕业设计化妆品销售网站源码+mysql数据库+系统+lw文档+部署
- 使用python为Excel插入附件
- 【目标检测】0、目标检测方法发展综述
- 基于FPGA的频率计
- 单片机c语言中u8是什么意思,stm32常用数据类型 U8、U16、U32到底代表什么?
- L2-026 小字辈——BFS DFS 并查集-三种方法
- Unity Web自适应浏览器