今天的內容我們主要圍繞四個點進行展開介紹。
這四點具體是什麼意思呢?
首先啟動專案:cloud-alibaba-sentinel-8006
在官方的介紹中是這樣說的:關聯的資源達到閾值時,就限流自己。
這句話是什麼意思呢?用比較直白一點的話來講,假設我們有A和B兩個介面,當A關聯B介面,同時B介面的資源達到設定的閾值時,限流A。我們也可以理解成,當我們下游的服務出現存取壓力過大時,對上游的服務進行攔截和限流操作,例如:電商系統,當我們訂單系統超出承受閾值時,對我們支付模組進行限流。
例如:當我們關聯order介面達到我們設定的閾值時,限流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介面新增流控規則
在這裡我們需要使用到postMan
工具,來模擬並行存取,用它來測試我們的order介面的並行存取。
在這裡的意思是25個執行緒0.25秒跑一次,當我們跑起來之後,再去存取pay介面就可以看到以下資訊
當我們對order介面進行並行存取的時候,這個時候我們去存取pay介面,就可以看到pay介面返回限流資訊
鏈路的意思是值當某個介面過來的資源達到閾值時,開啟限流,主要是針對於請求來源的微服務,具有更細顆粒度。
比如在一個服務應用中,多個(pay和order)介面都呼叫了同一個服務中的方法(該方法必須使用註解 SentinelResource進行修飾),如果頻繁的去請求pay介面,並且達到設定的閾值,這麼時候我們再去請求order介面,那麼呼叫了同一服務的order介面就會被限流
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();
}
}
設定項web-context-unify
,這個設定的意思是說根據不同的URL進行鏈路限流,否則沒有效果
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
sentinel:
transport:
#設定Sentinel地址,就是我們的WEB介面
dashboard: localhost:8080
#Sentinel設定預設8719埠,被佔用埠會自動從+1,直到找到未被佔用的埠
port: 8719
# 設定為false
web-context-unify: false
我們存取pay介面和order介面後,需要對end進行流控規則的設定,也就是使用了SentinelResource
註解標註的方法進行流控設定。
那麼這個時候如果我們頻繁的去存取order介面的時候,就會出現異常的情況,直接丟擲錯誤提示,這個也是因為快速失敗在鏈路上的直接體現
參考檔案:https://sentinelguard.io/zh-cn/docs/flow-control.html
Warm Up 流量控制,也叫預熱或者冷啟動方式,會根據我們設定的規則,進行緩慢的流量放開,逐漸增加閾值上限,給系統一個反應時間,避免流量的突然增加,將系統壓垮的情況發生,主要用於預防我們系統長期處於穩定的流量存取下,突然流量的增加,將系統資源直接拉滿的情況.
在這裡我們主要弄明白兩個引數
單機閾值:12,這個表示我們存取最大閾值為12,但是第一次最大存取量為4,為什麼是4呢,看下面公式
預熱公式:閾值/coldFactor(預設值為3),經過預熱時間後才會達到閾值。
預熱時長:5 ,也就是說我們的請求會在五秒內單機閾值達到12的存取,比如第一次為4,後續在五秒內依次5/6/8/10,最後達到12的閾值
一般這種在秒殺或者電商節中會設定這樣的流控規則,就是為了防止突然流量的增加導致系統的奔潰。
當我們設定完流控規則以後,我們就來看一下效果,我們剛才設定的order的介面,如果當我們在頻繁的去存取order介面的時候,如果超過當前時間設定的閾值時,直接返回限流資訊。
在這裡我們直接用瀏覽器瘋狂的去重新整理,是時候體驗單身二十幾年的手速了,當然也可以使用postman介面去試,我們這邊手速比較快,直接用瀏覽器重新整理,我們可以看到下面的曲線圖:
藍色表示你拒絕的QPS,綠色表示通過的QPS,我們可以看到藍色成明顯的下降趨勢,而綠色成上升趨勢,也可以通過右邊的表格中看到,剛開始通過的只有四個,具體的有三個,後面通過慢慢增加,拒絕慢慢變少,這個就是我們Warm Up(預熱)的作用了
我們現在來介紹最後一個流控規則的使用,排隊等待會嚴格控制請求通過的間隔時間,讓請求穩定且勻速的通過,可以用來處理間隔性突發的高流量,例如搶票軟體,在某一秒或者一分鐘內有大量的請求到來,而接下來的一段時間裡處於空閒狀態,我們希望系統能夠在接下來的空餘時間裡也能出去這些請求,而不是直接拒絕。
以固定的間隔時間讓請求通過,當請求過來的時候,如果當前請求距離上一個請求通過的時間大於 規則預設值 ,則請求通過,如果當前請求預期通過時間小於 規則預設值 ,則進行排隊等待,如果預期通過時間超過最大排隊時間,直接拒絕請求。
Sentinel排隊等待是 漏銅演演算法+虛擬佇列機制實現的,目前排隊等待中不支援QPS>1000的場景
我們對pay介面進行設定,一秒鐘只處理一個QPS請求,其他的排隊,如果超過15秒則直接拒絕
pay介面調整,這裡我們給pay介面加上列印紀錄檔,方便我們看到具體效果
@GetMapping("/pay")
public String pay() {
// return "hello my name is pay ,wo shi boy";
log.info("pay介面,請求執行緒為:"+Thread.currentThread().getName());
return testService.end();
}
我們藉助postman來進行呼叫,說明手速始終更不上工具,還是工具香,這裡我們設定10個請求,沒有間隔時間
從下圖中我們可以看到,對於我們的請求,是一個QPS請求。
小結:流控規則就是針對不同的規則進行不同的設定,來滿足我們不用業務場景。