什么?Sentinel流控規(guī)則可以這樣玩?

前言

上一篇文章中,我們講解了關(guān)于sentinel基本介紹以及流控規(guī)則中直接和快速失敗的效果,有興趣的可以去看上一篇文章,今天,我們給大家?guī)砀釉敿?xì)的關(guān)于sentinel流控規(guī)則的介紹。今天的內(nèi)容我們主要圍繞四個(gè)點(diǎn)進(jìn)行展開介紹。

  • 流控模式 :關(guān)聯(lián)、鏈路
  • 流控效果 :Warm Up、排隊(duì)等待


這四點(diǎn)具體是什么意思呢?別急我們一個(gè)一個(gè)來做詳細(xì)的介紹,首先我們從關(guān)聯(lián)開始。

首先啟動(dòng)項(xiàng)目:cloud-alibaba-sentinel-8006

關(guān)聯(lián)

在官方的介紹中是這樣說的:關(guān)聯(lián)的資源達(dá)到閾值時(shí),就限流自己。

這句話是什么意思呢?用比較直白一點(diǎn)的話來講,假設(shè)我們有A和B兩個(gè)接口,當(dāng)A關(guān)聯(lián)B接口,同時(shí)B接口的資源達(dá)到設(shè)定的閾值時(shí),限流A。我們也可以理解成,當(dāng)我們下游的服務(wù)出現(xiàn)訪問壓力過大時(shí),對(duì)上游的服務(wù)進(jìn)行攔截和限流操作,例如:電商系統(tǒng),當(dāng)我們訂單系統(tǒng)超出承受閾值時(shí),對(duì)我們支付模塊進(jìn)行限流。

例如:當(dāng)我們關(guān)聯(lián)order接口達(dá)到我們?cè)O(shè)定的閾值時(shí),限流pay的接口訪問。

@Slf4j
@RestController
public class TestController {

    @GetMapping("/pay")
    public String pay() {
        return "hello my name is pay ,wo shi boy";
    }

    @GetMapping("/order")
    public String order(){
        return "hi my name is order, me is girl";
    }

}

給pay接口添加流控規(guī)則

在這里我們需要使用到postMan工具,來模擬并發(fā)訪問,用它來測試我們的order接口的并發(fā)訪問。

在這里的意思是25個(gè)線程0.25秒跑一次,當(dāng)我們跑起來之后,再去訪問pay接口就可以看到以下信息


當(dāng)我們對(duì)order接口進(jìn)行并發(fā)訪問的時(shí)候,這個(gè)時(shí)候我們?nèi)ピL問pay接口,就可以看到pay接口返回限流信息

鏈路

接下來我們就來看一下流控模式中的鏈路,鏈路的意思是值當(dāng)某個(gè)接口過來的資源達(dá)到閾值時(shí),開啟限流,主要是針對(duì)于請(qǐng)求來源的微服務(wù),具有更細(xì)顆粒度。

比如在一個(gè)服務(wù)應(yīng)用中,多個(gè)(pay和order)接口都調(diào)用了同一個(gè)服務(wù)中的方法(該方法必須使用注解 SentinelResource進(jìn)行修飾),如果頻繁的去請(qǐng)求pay接口,并且達(dá)到設(shè)定的閾值,這么時(shí)候我們?cè)偃フ?qǐng)求order接口,那么調(diào)用了同一服務(wù)的order接口就會(huì)被限流

test類

@Service
public class TestService {
    // 定義限流資源
    @SentinelResource("end")
    public String end(){
        return "end method";
    }
}

controller類

@Slf4j
@RestController
public class TestController {

    @Autowired
    private TestService testService;

    @GetMapping("/pay")
    public String pay() {
        return testService.end();
    }

    @GetMapping("/order")
    public String order(){
        return testService.end();
    }

}

配置項(xiàng)web-context-unify,這個(gè)配置的意思是說根據(jù)不同的URL進(jìn)行鏈路限流,否則沒有效果

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel地址,就是我們的WEB界面
        dashboard: localhost:8080
        #Sentinel配置默認(rèn)8719端口,被占用端口會(huì)自動(dòng)從+1,直到找到未被占用的端口
        port: 8719
        # 配置為false
      web-context-unify: false

我們?cè)L問pay接口和order接口后,需要對(duì)end進(jìn)行流控規(guī)則的配置,也就是使用了SentinelResource注解標(biāo)注的方法進(jìn)行流控設(shè)置。

那么這個(gè)時(shí)候如果我們頻繁的去訪問order接口的時(shí)候,就會(huì)出現(xiàn)異常的情況,直接拋出錯(cuò)誤提示,這個(gè)也是因?yàn)榭焖偈≡阪溌飞系闹苯芋w現(xiàn)

Warm Up

參考文檔:https://sentinelguard.io/zh-cn/docs/flow-control.html

Warm Up 流量控制,也叫預(yù)熱或者冷啟動(dòng)方式,會(huì)根據(jù)我們?cè)O(shè)定的規(guī)則,進(jìn)行緩慢的流量放開,逐漸增加閾值上限,給系統(tǒng)一個(gè)反應(yīng)時(shí)間,避免流量的突然增加,將系統(tǒng)壓垮的情況發(fā)生,主要用于預(yù)防我們系統(tǒng)長期處于穩(wěn)定的流量訪問下,突然流量的增加,將系統(tǒng)資源直接拉滿的情況.

在這里我們主要弄明白兩個(gè)參數(shù)

單機(jī)閾值:12,這個(gè)表示我們?cè)L問最大閾值為12,但是第一次最大訪問量為4,為什么是4呢,看下面公式

預(yù)熱公式:閾值/coldFactor(默認(rèn)值為3),經(jīng)過預(yù)熱時(shí)間后才會(huì)達(dá)到閾值。

預(yù)熱時(shí)長:5 ,也就是說我們的請(qǐng)求會(huì)在五秒內(nèi)單機(jī)閾值達(dá)到12的訪問,比如第一次為4,后續(xù)在五秒內(nèi)依次5/6/8/10,最后達(dá)到12的閾值

一般這種在秒殺或者電商節(jié)中會(huì)設(shè)置這樣的流控規(guī)則,就是為了防止突然流量的增加導(dǎo)致系統(tǒng)的奔潰。

當(dāng)我們?cè)O(shè)置完流控規(guī)則以后,我們就來看一下效果,我們剛才設(shè)置的order的接口,如果當(dāng)我們?cè)陬l繁的去訪問order接口的時(shí)候,如果超過當(dāng)前時(shí)間設(shè)定的閾值時(shí),直接返回限流信息。

在這里我們直接用瀏覽器瘋狂的去刷新,是時(shí)候體驗(yàn)單身二十幾年的手速了,當(dāng)然也可以使用postman接口去試,我們這邊手速比較快,直接用瀏覽器刷新,我們可以看到下面的曲線圖:

藍(lán)色表示你拒絕的QPS,綠色表示通過的QPS,我們可以看到藍(lán)色成明顯的下降趨勢,而綠色成上升趨勢,也可以通過右邊的表格中看到,剛開始通過的只有四個(gè),具體的有三個(gè),后面通過慢慢增加,拒絕慢慢變少,這個(gè)就是我們Warm Up(預(yù)熱)的作用了

排隊(duì)等待

我們現(xiàn)在來介紹最后一個(gè)流控規(guī)則的使用,排隊(duì)等待會(huì)嚴(yán)格控制請(qǐng)求通過的間隔時(shí)間,讓請(qǐng)求穩(wěn)定且勻速的通過,可以用來處理間隔性突發(fā)的高流量,例如搶票軟件,在某一秒或者一分鐘內(nèi)有大量的請(qǐng)求到來,而接下來的一段時(shí)間里處于空閑狀態(tài),我們希望系統(tǒng)能夠在接下來的空余時(shí)間里也能出去這些請(qǐng)求,而不是直接拒絕。

以固定的間隔時(shí)間讓請(qǐng)求通過,當(dāng)請(qǐng)求過來的時(shí)候,如果當(dāng)前請(qǐng)求距離上一個(gè)請(qǐng)求通過的時(shí)間大于 規(guī)則預(yù)設(shè)值 ,則請(qǐng)求通過,如果當(dāng)前請(qǐng)求預(yù)期通過時(shí)間小于 規(guī)則預(yù)設(shè)值 ,則進(jìn)行排隊(duì)等待,如果預(yù)期通過時(shí)間超過最大排隊(duì)時(shí)間,直接拒絕請(qǐng)求。

Sentinel排隊(duì)等待是 漏銅算法+虛擬隊(duì)列機(jī)制實(shí)現(xiàn)的,目前排隊(duì)等待中不支持QPS>1000的場景

我們對(duì)pay接口進(jìn)行設(shè)置,一秒鐘只處理一個(gè)QPS請(qǐng)求,其他的排隊(duì),如果超過15秒則直接拒絕

pay接口調(diào)整,這里我們給pay接口加上打印日志,方便我們看到具體效果

    @GetMapping("/pay")
    public String pay() {
//        return "hello my name is pay ,wo shi boy";
        log.info("pay接口,請(qǐng)求線程為:"+Thread.currentThread().getName());
        return testService.end();
    }

我們借助postman來進(jìn)行調(diào)用,說明手速始終更不上工具,還是工具香,這里我們?cè)O(shè)置10個(gè)請(qǐng)求,沒有間隔時(shí)間

從下圖中我們可以看到,對(duì)于我們的請(qǐng)求,是一個(gè)QPS請(qǐng)求。

總結(jié)

到這里呢,我們的流控規(guī)則就講完了,主要是針對(duì)不同的規(guī)則進(jìn)行不同的設(shè)定,來滿足我們不用業(yè)務(wù)場景,可能會(huì)有一點(diǎn)點(diǎn)的小饒,但是如果親自操作之后,會(huì)感覺原來是這樣,感興趣的小伙伴可以自己動(dòng)手試一試,源碼都已經(jīng)上傳了,只有動(dòng)手了才能感受到其中的快樂,趕緊去試一試吧。


文章轉(zhuǎn)載自: https://muxiaonong.blog.csdn.net


公眾號(hào):牧小農(nóng),微信掃碼關(guān)注或搜索公眾號(hào)名稱