亿级流量网站架构核心技术:限流详解之节流

开发 开发工具
有时候我们想在特定时间窗口内对重复的相同事件最多只处理一次,或者想限制多个连续相同事件最小执行时间间隔,那么可使用节流(Throttle)实现,其防止多个相同事件连续重复执行。

上接聊聊高并发系统之限流特技-1聊聊高并发系统之限流特技-2,本篇摘自《亿级流量网站架构核心技术》第四章 限流详解,在之前两篇文章的基础上增加了节流部分。

有时候我们想在特定时间窗口内对重复的相同事件最多只处理一次,或者想限制多个连续相同事件最小执行时间间隔,那么可使用节流(Throttle)实现,其防止多个相同事件连续重复执行。节流主要有如下几种用法:throttleFirst、throttleLast、throttleWithTimeout。

1. throttleFirst/throttleLast

throttleFirst/ throttleLast是指在一个时间窗口内,如果有重复的多个相同事件要处理,则只处理***个或***一个。其相当于一个事件频率控制器,把一段时间内重复的多个相同事件变为一个,减少事件处理频率,从而减少无用处理,提升性能。

throttleFirst在一个时间窗口内只会处理该时间窗口内的***个事件

如上图所示,throttleFirst在一个时间窗口内只会处理该时间窗口内的***个事件。

而throttleLast会处理该时间窗口内的***一个事件。

一个场景是网页中的resize、scroll和mousemove 事件,当我们改变浏览器大小时会触发resize事件,而滚动页面元素时会触发scroll事件。当我们快速连续执行这些操作时会连续触发这些事件,那么可能因造成UI反应慢、浏览器卡顿,因此节流就派上用场了。对于前端开发可以使用jquery-throttle-debounce-plugin实现,而Android开发可以使用RxAndroid实现。

2 throttleWithTimeout

throttleWithTimeout也叫做debounce(去抖),限制两个连续事件的先后执行时间不得小于某个时间窗口。

throttleWithTimeout限制两个连续事件的最小间隔时间窗口

如上图所示,throttleWithTimeout限制两个连续事件的最小间隔时间窗口。throttleFirst/ throttleLast是基于决定时间做的处理,是以固定时间窗口为基准,对同一个固定时间窗口内的多个连续事件最多只处理一个。而throttleWithTimeout是基于两个连续事件的相对时间,当两个连续事件的间隔时间小于最小间隔时间窗口,就会丢弃上一个事件,而如果***一个事件等待了最小间隔时间窗口后还没有新的事件到来,那么会处理***一个事件。

如搜索关键词自动补全,如果用户每录入一个字就发送一次请求,而先输入的字的自动补全会被很快到来的下一个字符覆盖,那么会导致先期的自动补全是无用的。throttleWithTimeout就是来解决这个问题的,通过它来减少频繁的网络请求,避免每输入一个字就导致一次请求。

使用RxJava 1.2.0实现的测试代码。

  1. Observable 
  2.         .create(new Observable.OnSubscribe<Integer>(){ 
  3.             @Override 
  4.             public void call(Subscriber<? super Integer> subscriber) { 
  5.                 //next实现:Thread.sleep(millis); subscriber.onNext(i); 
  6.                 next(subscriber, 1,0);  //0ms 
  7.                 next(subscriber, 2,50); //50ms 
  8.                 next(subscriber, 3,50); //100ms 
  9.                 next(subscriber, 4,30); //130ms 
  10.                 next(subscriber, 5, 40); //170ms 
  11.                 next(subscriber, 6,130); //300ms 
  12.                 subscriber.onCompleted(); 
  13.             } 
  14.         }) 
  15.         .subscribeOn(Schedulers.newThread()) 
  16.         .throttleWithTimeout(100,TimeUnit.MILLISECONDS) 
  17.         .subscribe(new Subscriber<Integer>() { 
  18.             …… 
  19.             @Override 
  20.             public void onNext(Integer i) { 
  21.                 System.out.println("==" + i); 
  22.             } 
  23.         }); 

【本文是51CTO专栏作者张开涛的原创文章,作者微信公众号:开涛的博客( kaitao-1234567)】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2016-11-30 13:23:39

京东商品搜索商品搜索引擎

2021-10-12 10:00:25

架构运维技术

2021-12-03 10:47:28

WOT技术峰会技术

2021-10-14 09:51:17

架构运维技术

2023-06-14 08:49:22

PodKubernetes

2020-01-17 11:00:23

流量系统架构

2017-03-08 10:06:11

Java技术点注解

2016-12-12 09:01:47

Amazon Go核心技术

2022-10-11 08:37:43

Servlet配置版本

2016-11-23 12:55:09

京东活动系统流量

2024-08-23 11:38:05

2021-03-02 07:54:18

流量网关设计

2022-05-07 14:31:46

物联网

2024-05-27 08:32:45

2017-04-06 12:43:48

2011-08-23 17:12:22

MySQL支撑百万级流

2020-09-01 07:49:14

JVM流量系统

2024-10-28 08:01:11

2017-06-08 11:54:40

亿级推广流量

2009-06-26 16:01:39

EJB组织开发EJB容器EJB
点赞
收藏

51CTO技术栈公众号