一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - JAVA教程 - RateLimit-使用guava來做接口限流代碼示例

RateLimit-使用guava來做接口限流代碼示例

2021-03-24 14:33jiesa JAVA教程

這篇文章主要介紹了RateLimit-使用guava來做接口限流代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下

本文主要研究的是ratelimit-使用guava來做接口限流的相關(guān)內(nèi)容,具體如下。

一、問題描述

  某天a君突然發(fā)現(xiàn)自己的接口請求量突然漲到之前的10倍,沒多久該接口幾乎不可使用,并引發(fā)連鎖反應(yīng)導(dǎo)致整個(gè)系統(tǒng)崩潰。如何應(yīng)對這種情況呢?生活給了我們答案:比如老式電閘都安裝了保險(xiǎn)絲,一旦有人使用超大功率的設(shè)備,保險(xiǎn)絲就會(huì)燒斷以保護(hù)各個(gè)電器不被強(qiáng)電流給燒壞。同理我們的接口也需要安裝上“保險(xiǎn)絲”,以防止非預(yù)期的請求對系統(tǒng)壓力過大而引起的系統(tǒng)癱瘓,當(dāng)流量過大時(shí),可以采取拒絕或者引流等機(jī)制。

二、常用的限流算法

常用的限流算法有兩種:漏桶算法和令牌桶算法。

漏桶算法思路很簡單,請求先進(jìn)入到漏桶里,漏桶以一定的速度出水,當(dāng)水請求過大會(huì)直接溢出,可以看出漏桶算法能強(qiáng)行限制數(shù)據(jù)的傳輸速率。

RateLimit-使用guava來做接口限流代碼示例

圖1 漏桶算法示意圖

對于很多應(yīng)用場景來說,除了要求能夠限制數(shù)據(jù)的平均傳輸速率外,還要求允許某種程度的突發(fā)傳輸。這時(shí)候漏桶算法可能就不合適了,令牌桶算法更為適合。如圖2所示,令牌桶算法的原理是系統(tǒng)會(huì)以一個(gè)恒定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個(gè)令牌,當(dāng)桶里沒有令牌可取時(shí),則拒絕服務(wù)。

RateLimit-使用guava來做接口限流代碼示例

圖2 令牌桶算法示意圖

三、限流工具類ratelimiter

  google開源工具包guava提供了限流工具類ratelimiter,該類基于“令牌桶算法”,非常方便使用。該類的接口具體的使用請參考:ratelimiter使用實(shí)踐。

ratelimiter 使用demo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package ratelimite;
import com.google.common.util.concurrent.ratelimiter;
public class ratelimiterdemo {
    public static void main(string[] args) {
        testnoratelimiter();
        testwithratelimiter();
    }
    public static void testnoratelimiter() {
        long start = system.currenttimemillis();
        for (int i = 0; i < 10; i++) {
            system.out.println("call execute.." + i);
        }
        long end = system.currenttimemillis();
        system.out.println(end - start);
    }
    public static void testwithratelimiter() {
        long start = system.currenttimemillis();
        ratelimiter limiter = ratelimiter.create(10.0);
        // 每秒不超過10個(gè)任務(wù)被提交
        for (int i = 0; i < 10; i++) {
            limiter.acquire();
            // 請求ratelimiter, 超過permits會(huì)被阻塞
            system.out.println("call execute.." + i);
        }
        long end = system.currenttimemillis();
        system.out.println(end - start);
    }
}

四 guava并發(fā):listenablefuture與ratelimiter示例

概念

listenablefuture顧名思義就是可以監(jiān)聽的future,它是對java原生future的擴(kuò)展增強(qiáng)。我們知道future表示一個(gè)異步計(jì)算任務(wù),當(dāng)任務(wù)完成時(shí)可以得到計(jì)算結(jié)果。如果我們希望一旦計(jì)算完成就拿到結(jié)果展示給用戶或者做另外的計(jì)算,就必須使用另一個(gè)線程不斷的查詢計(jì)算狀態(tài)。這樣做,代碼復(fù)雜,而且效率低下。使用listenablefuture guava幫我們檢測future是否完成了,如果完成就自動(dòng)調(diào)用回調(diào)函數(shù),這樣可以減少并發(fā)程序的復(fù)雜度。

推薦使用第二種方法,因?yàn)榈诙N方法可以直接得到future的返回值,或者處理錯(cuò)誤情況。本質(zhì)上第二種方法是通過調(diào)動(dòng)第一種方法實(shí)現(xiàn)的,做了進(jìn)一步的封裝。

另外listenablefuture還有其他幾種內(nèi)置實(shí)現(xiàn):

settablefuture:不需要實(shí)現(xiàn)一個(gè)方法來計(jì)算返回值,而只需要返回一個(gè)固定值來做為返回值,可以通過程序設(shè)置此future的返回值或者異常信息

checkedfuture: 這是一個(gè)繼承自listenablefuture接口,他提供了checkedget()方法,此方法在future執(zhí)行發(fā)生異常時(shí),可以拋出指定類型的異常。

ratelimiter類似于jdk的信號量semphore,他用來限制對資源并發(fā)訪問的線程數(shù),本文介紹ratelimiter使用

代碼示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import java.util.concurrent.callable;
import java.util.concurrent.executionexception;
import java.util.concurrent.executors;
import java.util.concurrent.timeunit;
import com.google.common.util.concurrent.futurecallback;
import com.google.common.util.concurrent.futures;
import com.google.common.util.concurrent.listenablefuture;
import com.google.common.util.concurrent.listeningexecutorservice;
import com.google.common.util.concurrent.moreexecutors;
import com.google.common.util.concurrent.ratelimiter;
public class listenablefuturedemo {
    public static void main(string[] args) {
        testratelimiter();
        testlistenablefuture();
    }
    /**
   * ratelimiter類似于jdk的信號量semphore,他用來限制對資源并發(fā)訪問的線程數(shù)
   */
    public static void testratelimiter() {
        listeningexecutorservice executorservice = moreexecutors
                .listeningdecorator(executors.newcachedthreadpool());
        ratelimiter limiter = ratelimiter.create(5.0);
        // 每秒不超過4個(gè)任務(wù)被提交
        for (int i = 0; i < 10; i++) {
            limiter.acquire();
            // 請求ratelimiter, 超過permits會(huì)被阻塞
            final listenablefuture<integer> listenablefuture = executorservice
                      .submit(new task("is "+ i));
        }
    }
    public static void testlistenablefuture() {
        listeningexecutorservice executorservice = moreexecutors
                .listeningdecorator(executors.newcachedthreadpool());
        final listenablefuture<integer> listenablefuture = executorservice
                .submit(new task("testlistenablefuture"));
        //同步獲取調(diào)用結(jié)果
        try {
            system.out.println(listenablefuture.get());
        }
        catch (interruptedexception e1) {
            e1.printstacktrace();
        }
        catch (executionexception e1) {
            e1.printstacktrace();
        }
        //第一種方式
        listenablefuture.addlistener(new runnable() {
            @override
                  public void run() {
                try {
                    system.out.println("get listenable future's result "
                                  + listenablefuture.get());
                }
                catch (interruptedexception e) {
                    e.printstacktrace();
                }
                catch (executionexception e) {
                    e.printstacktrace();
                }
            }
        }
        , executorservice);
        //第二種方式
        futures.addcallback(listenablefuture, new futurecallback<integer>() {
            @override
                  public void onsuccess(integer result) {
                system.out
                            .println("get listenable future's result with callback "
                                + result);
            }
            @override
                  public void onfailure(throwable t) {
                t.printstacktrace();
            }
        }
        );
    }
}
class task implements callable<integer> {
    string str;
    public task(string str){
        this.str = str;
    }
    @override
      public integer call() throws exception {
        system.out.println("call execute.." + str);
        timeunit.seconds.sleep(1);
        return 7;
    }
}

guava版本

?
1
2
3
4
5
<dependency>
      <groupid>com.google.guava</groupid>
      <artifactid>guava</artifactid>
      <version>14.0.1</version>
    </dependency>

總結(jié)

以上就是本文關(guān)于ratelimit-使用guava來做接口限流代碼示例的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/JIESA/article/details/50412027

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产亚洲人成网站在线观看不卡 | 调教女高中生第3部分 | 日韩hd高清xxxⅹ | 无人在线高清免费看 | 996免费视频国产在线播放 | bt天堂在线最新版在线 | 亚洲精品国产乱码AV在线观看 | 国产免费成人在线视频 | 精品国产成人a区在线观看 精品国产91久久久久久久 | 九九久久国产精品免费热6 九九精品视频一区二区三区 | 亚洲日本中文字幕天天更新 | 亚洲日韩精品欧美一区二区一 | 欧美a级v片不卡在线观看 | a v在线男人的天堂观看免费 | 国产精品免费视频一区一 | 亚欧毛片基地国产毛片基地 | 麻麻与子乱肉小说怀孕 | 国产精品视频第一页 | 国产hd老头老太婆 | 国产老肥熟xxxx| 边摸边吃奶边做爽视频免费 | 西施打开双腿下面好紧 | caoporn人人| 日韩性生活片 | 久久九九有精品国产23百花影院 | 水多多www视频在线观看高清 | 91国内精品线免费播放 | 色臀网站| 丝瓜视频在线观看污 | 色花堂中文字幕98堂网址 | 国产精品高清一区二区三区 | 亚洲AV久久无码精品九号软件 | 精品久久久久久久久免费影院 | 4444kk在线看片 | 婷婷综合缴情亚洲五月伊 | 黄a一级 | 娇妻被健身教练挺进小说阅读 | 91真人毛片一级在线播放 | 国产灌醉 | japanese乱子mate| 亚洲欧美精品一区天堂久久 |