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

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

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

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

RateLimit-使用guava來(lái)做接口限流代碼示例

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

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

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

一、問(wèn)題描述

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

二、常用的限流算法

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

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

RateLimit-使用guava來(lái)做接口限流代碼示例

圖1 漏桶算法示意圖

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

RateLimit-使用guava來(lái)做接口限流代碼示例

圖2 令牌桶算法示意圖

三、限流工具類(lèi)ratelimiter

  google開(kāi)源工具包guava提供了限流工具類(lèi)ratelimiter,該類(lèi)基于“令牌桶算法”,非常方便使用。該類(lèi)的接口具體的使用請(qǐng)參考: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);
        // 每秒不超過(guò)10個(gè)任務(wù)被提交
        for (int i = 0; i < 10; i++) {
            limiter.acquire();
            // 請(qǐng)求ratelimiter, 超過(guò)permits會(huì)被阻塞
            system.out.println("call execute.." + i);
        }
        long end = system.currenttimemillis();
        system.out.println(end - start);
    }
}

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

概念

listenablefuture顧名思義就是可以監(jiān)聽(tīng)的future,它是對(duì)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幫我們檢測(cè)future是否完成了,如果完成就自動(dòng)調(diào)用回調(diào)函數(shù),這樣可以減少并發(fā)程序的復(fù)雜度。

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

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

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

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

ratelimiter類(lèi)似于jdk的信號(hào)量semphore,他用來(lái)限制對(duì)資源并發(fā)訪問(wèn)的線程數(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類(lèi)似于jdk的信號(hào)量semphore,他用來(lái)限制對(duì)資源并發(fā)訪問(wèn)的線程數(shù)
   */
    public static void testratelimiter() {
        listeningexecutorservice executorservice = moreexecutors
                .listeningdecorator(executors.newcachedthreadpool());
        ratelimiter limiter = ratelimiter.create(5.0);
        // 每秒不超過(guò)4個(gè)任務(wù)被提交
        for (int i = 0; i < 10; i++) {
            limiter.acquire();
            // 請(qǐng)求ratelimiter, 超過(guò)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來(lái)做接口限流代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男人天堂色男人 | 手机看片www xiao2b cm | 手机在线免费观看日本推理片 | 大妹子最新视频在线观看 | 亚洲日日做天天做日日谢 | 午夜福利合集1000在线 | 91精品国产91热久久p | 色久久一个亚洲综合网 | 草草在线视频 | 俺去也亚洲色图 | 欧美交换乱理伦片120秒 | 思思玖玖 | 国产欧美日韩不卡一区二区三区 | 亚洲AV无码专区国产乱码网站 | 亚洲高清网站 | 天天插综合网 | 亚洲国产网址 | 亚洲国产欧美目韩成人综合 | 国产91在线精品 | 短篇小说肉 | 国产精品日本一区二区三区在线看 | 亚洲精品综合网 | 精品国产一区二区三区在线 | 成人免费观看一区二区 | 四虎成人免费视频 | 日韩在线视频一区二区三区 | 日本一卡2卡3卡4卡乱 | 99美国热 | 男人含玉势出嫁束器 | 成年性香蕉漫画在线观看 | 午夜AV亚洲一码二中文字幕青青 | 三级午夜宅宅伦不卡在线 | 色婷婷综合和线在线 | 欧美黑人换爱交换乱理伦片 | 日本中文字幕在线精品 | 好猛好紧好硬使劲好大刺激视频 | 欧美日韩中文国产一区 | 18国产精品白浆在线观看免费 | 国内精品久久久久久中文字幕 | 俄罗斯妈妈235 | 欧美同志video 在线观看 |