常用的限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,例如一秒钟10枚令牌,实际业务在每次响应请求之前都从桶中获取令牌,只有取到令牌的请求才会被成功响应,获取的方式有两种:阻塞等待令牌或者取不到立即返回失败,下图来自网上:

本次实战,我们用的是guava的RateLimiter,场景是spring mvc在处理请求时候,从桶中申请令牌,申请到了就成功响应,申请不到时直接返回失败;

对于的源码可以在我的git下载,地址是:https://github.com/zq2599/blog_demos,里面有多个工程,本次实战的工程为guavalimitdemo,如下图红框所示:

这是一个maven工程,所以首先我们在pom中把guava的依赖添加进来:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>18.0</version></dependency>

把限流服务封装到一个类中AccessLimitService,提供tryAcquire()方法,用来尝试获取令牌,返回true表示获取到,如下所示:

@Service
public class AccessLimitService {//每秒只发出5个令牌RateLimiter rateLimiter = RateLimiter.create(5.0);/*** 尝试获取令牌* @return*/public boolean tryAcquire(){return rateLimiter.tryAcquire();}
}

调用方是个普通的controller,每次收到请求的时候都尝试去获取令牌,获取成功和失败打印不同的信息,如下:

@Controller
public class HelloController {private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Autowiredprivate AccessLimitService accessLimitService;@RequestMapping("/access")@ResponseBodypublic String access(){//尝试获取令牌if(accessLimitService.tryAcquire()){//模拟业务执行500毫秒try {Thread.sleep(500);}catch (InterruptedException e){e.printStackTrace();}return "aceess success [" + sdf.format(new Date()) + "]";}else{return "aceess limit [" + sdf.format(new Date()) + "]";}}
}

以上就是服务端的代码了,打包部署在tomcat上即可,接下来我们写一个类,十个线程并发访问上面写的controller:

public class AccessClient {ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);/*** get请求* @param realUrl* @return*/public static String sendGet(URL realUrl) {String result = "";BufferedReader in = null;try {// 打开和URL之间的连接URLConnection connection = realUrl.openConnection();// 设置通用的请求属性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立实际的连接connection.connect();// 定义 BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("发送GET请求出现异常!" + e);e.printStackTrace();}// 使用finally块来关闭输入流finally {try {if (in != null) {in.close();}} catch (Exception e2) {e2.printStackTrace();}}return result;}public void access() throws Exception{final URL url = new URL("http://localhost:8080/guavalimitdemo/access");for(int i=0;i<10;i++) {fixedThreadPool.submit(new Runnable() {public void run() {System.out.println(sendGet(url));}});}fixedThreadPool.shutdown();fixedThreadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);}public static void main(String[] args) throws Exception{AccessClient accessClient = new AccessClient();accessClient.access();}
}

直接执行AccessClient的main方法,可以看到结果如下:

部分请求由于获取的令牌可以成功执行,其余请求没有拿到令牌,我们可以根据实际业务来做区分处理。还有一点要注意,我们通过RateLimiter.create(5.0)配置的是每一秒5枚令牌,但是限流的时候发出的是6枚,改用其他值验证,也是实际的比配置的大1。

以上就是快速实现限流的实战过程,此处仅是单进程服务的限流,而实际的分布式服务中会考虑更多因素,会复杂很多。

欢迎关注我的公众号

实战限流(guava的RateLimiter)相关推荐

  1. java guava限流,Guava的RateLimiter实现接口限流

    最近开发需求中有需要对后台接口进行限流处理,整理了一下基本使用方法. 首先添加guava依赖: com.google.guava guava 23.0 然后封装RateLimiter适用对多接口的限制 ...

  2. java limit_简单的限流 java实现 RateLimiter

    1. 基于QPS的限流 即单位时间的请求数不能超过一个阈值 package com.multiplyzero.mz.core.rpc; import java.util.concurrent.Time ...

  3. Guava RateLimiter限流源码解析和实例应用

    2019独角兽企业重金招聘Python工程师标准>>> 在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是 ...

  4. 使用Guava的RateLimiter做限流

    一.问题描述   某天A君突然发现自己的接口请求量突然涨到之前的10倍,没多久该接口几乎不可使用,并引发连锁反应导致整个系统崩溃.如何应对这种情况呢?生活给了我们答案:比如老式电闸都安装了保险丝,一旦 ...

  5. SpringBoot 2.0 + 阿里巴巴 Sentinel 动态限流实战

    转载 https://www.cnblogs.com/smallSevens/p/11531534.html 前言 在从0到1构建分布式秒杀系统和打造十万博文系统中,限流是不可缺少的一个环节,在系统能 ...

  6. 我们公司使用了 5 年的系统限流方案 ,从实现到部署实战详解,稳的一B

    前言 最近几年,随着微服务的流行,服务和服务之间的依赖越来越强,调用关系越来越复杂,服务和服务之间的稳定性越来越重要.在遇到突发的请求量激增,恶意的用户访问,亦或请求频率过高给下游服务带来较大压力时, ...

  7. Guava——平滑限流

    1.常用限流方法 对于一个应用系统来说一定会有极限并发/请求数,即总有一个TPS/QPS阀值,如果超了阀值则系统就会不响应用户请求或响应的非常慢,因此我们最好进行过载保护,防止大量请求涌入击垮系统. ...

  8. SpringMvc 限流之 RateLimiter

    概念 限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务.排队或等待.降级等处理 常用限流算法 常用的限流算法有两种:漏桶算法 ...

  9. 限流-RateLimiter

    限流-RateLimiter 工作中对外提供的API 接口设计都要考虑限流,如果不考虑限流,会成系统的连锁反应,轻者响应缓慢,重者系统宕机,整个业务线崩溃,如何应对这种情况呢,我们可以对请求进行引流或 ...

最新文章

  1. 2019,商业智能的10大未来趋势
  2. Boost之正则表达式_[转]
  3. java.lang.OutOfMemoryError处理错误
  4. java inputreader_Java之InputStreamReader类的实现
  5. python的实例属性和静态属性表_Python:类属性,实例属性,私有属性与静态方法,类方法,实例方法...
  6. maven deploy上传本地jar至私服
  7. 【转】我们到底为了什么钻研技术?
  8. 发布你的程序包到Nuget
  9. Opencv---remap函数的实现
  10. 电脑c语言翻译器,C语言window--在线翻译器.doc-资源下载人人文库网
  11. 变形监测与数据处理复习总结
  12. 开源)嗨,Java,你可以生成金山词霸的二维码分享海报吗?
  13. Jquery实现城市选择(省市联动)
  14. 电驴服务器更新的作用,[转载]【强烈推荐更新】最新电驴服务器列表(2013.7.11)...
  15. 拓嘉辰丰:影响拼多多直通车推广效果的因素有哪些?
  16. 《高效团队待人技巧》的读书笔记
  17. oracle12c cdb修改,Oracle 12C CDB字符集修改
  18. python 打印机控制_python调用打印机
  19. Distilling Object Detectors via Decoupled Features
  20. 权威典藏版:漫游费的前世今生(下)

热门文章

  1. HTB-Inject
  2. 学习索引结构的一些案例——Jeff Dean在SystemML会议上发布的论文
  3. 高压输电线路巡检机器人问世
  4. 如何查看智能手机的IP地址
  5. 7N60-ASEMI低功耗mos管7N60
  6. 制作PHP安装程序的原理和步骤
  7. Android入门之ScrollView
  8. 怎么把加密的PDF上面的文字复制下来?
  9. 【Metashape精品教程11】生成密集点云和TDOM成果
  10. 360hackgame writeup