流量控制理论与Sentinel
sentinel官方文檔:https://sentinelguard.io/zh-cn/docs/introduction.html
流量控制理論策略:
漏桶算法:
適用:漏桶策略適用于間隔性突發(fā)流量且流量不用即時(shí)處理的場(chǎng)景
代表框架:Sentinel 中的勻速排隊(duì)限流策略,分布式追蹤系統(tǒng) Jaeger 中采集策略為速率限制類型。
有一個(gè)固定容量的水桶,桶底有一個(gè)小洞,水桶可以接收任意速率的水流,但無論水桶里有多少水,水從小洞流出的速率始終不變,桶里的水滿了之后,水就會(huì)溢出。
優(yōu)點(diǎn):平滑流量,做到了流量整形,即無論流量多大,即便是突發(fā)的大流量,輸出依舊是一個(gè)穩(wěn)定的流量。
缺點(diǎn):對(duì)于突發(fā)流量的情況,因?yàn)榉?wù)器處理速度與正常流量的處理速度一致,會(huì)丟棄比較多的請(qǐng)求。
令牌桶算法:
適用:有突發(fā)特性的流量,且流量需要即時(shí)處理的場(chǎng)景。
代表框架:Guava 提供的限流工具類 RateLimiter。
有一個(gè)固定容量的存放令牌的桶,我們以固定速率向桶里放入令牌,桶滿時(shí)會(huì)丟棄多出的令牌。每當(dāng)請(qǐng)求到來時(shí),必須先到桶里取一個(gè)令牌才可被服務(wù)器處理,也就是說只有拿到了令牌的請(qǐng)求才會(huì)被服務(wù)器處理。所以,你可以將令牌理解為門卡,只有拿到了門卡才能順利進(jìn)入房間。
文章參考:https://cloud.tencent.com/developer/article/1663918
服務(wù)降級(jí)與熔斷
服務(wù)降級(jí):一般是指在服務(wù)器壓力劇增的時(shí)候,根據(jù)實(shí)際業(yè)務(wù)使用情況以及流量,對(duì)一些服務(wù)和頁(yè)面有策略的不處理或者用一種簡(jiǎn)單的方式進(jìn)行處理,從而釋放服務(wù)器資源的資源以保證核心業(yè)務(wù)的正常高效運(yùn)行,提供的是不完全的服務(wù)。
例如:在雙十一期間,壓力特別大時(shí),電商平臺(tái)完成訂單期間原本頁(yè)面上展示關(guān)聯(lián)商品推薦不再展示。
服務(wù)熔斷:應(yīng)對(duì)雪崩效應(yīng)的鏈路自我保護(hù)機(jī)制。當(dāng)某服務(wù)出現(xiàn)不可用或響應(yīng)超時(shí)的情況時(shí),為了防止該鏈路的其他服務(wù)和整個(gè)系統(tǒng)出現(xiàn)雪崩,暫時(shí)停止對(duì)該服務(wù)的調(diào)用。
sentinel
參考資料:http://c.biancheng.net/springcloud/sentinel.html
sentinel 基于以下屬性組合進(jìn)行流量控制。
| 資源名 | 流控規(guī)則的作用對(duì)象。 | - |
| 閾值 | 流控的閾值。 | - |
| 閾值類型 | 流控閾值的類型,包括 QPS 或并發(fā)線程數(shù)。 | QPS |
| 針對(duì)來源 | 流控針對(duì)的調(diào)用來源。 | default,表示不區(qū)分調(diào)用來源 |
| 流控模式 | 調(diào)用關(guān)系限流策略,包括直接、鏈路和關(guān)聯(lián)。 | 直接 |
| 流控效果 | 流控效果(直接拒絕、Warm Up、勻速排隊(duì)),不支持按調(diào)用關(guān)系限流。 | 直接拒絕 |
QPS :表示并發(fā)請(qǐng)求數(shù),即每秒鐘最多通過的請(qǐng)求數(shù)。
Sentinel 提供了 3 種熔斷策略,如下表所示。
| 慢調(diào)用比例 (SLOW_REQUEST_RATIO) | 選擇以慢調(diào)用比例作為閾值,需要設(shè)置允許的慢調(diào)用 RT(即最大響應(yīng)時(shí)間),若請(qǐng)求的響應(yīng)時(shí)間大于該值則統(tǒng)計(jì)為慢調(diào)用。 當(dāng)單位統(tǒng)計(jì)時(shí)長(zhǎng)(statIntervalMs)內(nèi)請(qǐng)求數(shù)目大于設(shè)置的最小請(qǐng)求數(shù)目,且慢調(diào)用的比例大于閾值,則接下來的熔斷時(shí)長(zhǎng)內(nèi)請(qǐng)求會(huì)自動(dòng)被熔斷。 經(jīng)過熔斷時(shí)長(zhǎng)后熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個(gè)請(qǐng)求響應(yīng)時(shí)間小于設(shè)置的慢調(diào)用 RT 則結(jié)束熔斷,若大于設(shè)置的慢調(diào)用 RT 則再次被熔斷。 |
| 異常比例 (ERROR_RATIO) | 當(dāng)單位統(tǒng)計(jì)時(shí)長(zhǎng)(statIntervalMs)內(nèi)請(qǐng)求數(shù)目大于設(shè)置的最小請(qǐng)求數(shù)目且異常的比例大于閾值,則在接下來的熔斷時(shí)長(zhǎng)內(nèi)請(qǐng)求會(huì)自動(dòng)被熔斷。 經(jīng)過熔斷時(shí)長(zhǎng)后熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個(gè)請(qǐng)求成功完成(沒有錯(cuò)誤)則結(jié)束熔斷,否則會(huì)再次被熔斷。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。 |
| 異常數(shù) (ERROR_COUNT) | 當(dāng)單位統(tǒng)計(jì)時(shí)長(zhǎng)內(nèi)的異常數(shù)目超過閾值之后會(huì)自動(dòng)進(jìn)行熔斷。 經(jīng)過熔斷時(shí)長(zhǎng)后熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個(gè)請(qǐng)求成功完成(沒有錯(cuò)誤)則結(jié)束熔斷,否則會(huì)再次被熔斷。 |
官方文檔上提供了另一大類的流量控制:
基于調(diào)用關(guān)系的流量控制:
根據(jù)調(diào)用方限流
ContextUtil.enter(resourceName, origin) 方法中的 origin 參數(shù)標(biāo)明了調(diào)用方身份。這些信息會(huì)在 ClusterBuilderSlot 中被統(tǒng)計(jì)。可通過以下命令來展示不同的調(diào)用方對(duì)同一個(gè)資源的調(diào)用數(shù)據(jù):
調(diào)用數(shù)據(jù)示例:
id: nodeA idx origin threadNum passedQps blockedQps totalQps aRt 1m-passed 1m-blocked 1m-total 1 caller1 0 0 0 0 0 0 0 0 2 caller2 0 0 0 0 0 0 0 0上面這個(gè)命令展示了資源名為 nodeA 的資源被兩個(gè)不同的調(diào)用方調(diào)用的統(tǒng)計(jì)。
限流規(guī)則中的 limitApp 字段用于根據(jù)調(diào)用方進(jìn)行流量控制。該字段的值有以下三種選項(xiàng),分別對(duì)應(yīng)不同的場(chǎng)景:
-
default:表示不區(qū)分調(diào)用者,來自任何調(diào)用者的請(qǐng)求都將進(jìn)行限流統(tǒng)計(jì)。如果這個(gè)資源名的調(diào)用總和超過了這條規(guī)則定義的閾值,則觸發(fā)限流。
-
{some_origin_name}:表示針對(duì)特定的調(diào)用者,只有來自這個(gè)調(diào)用者的請(qǐng)求才會(huì)進(jìn)行流量控制。例如 NodeA 配置了一條針對(duì)調(diào)用者caller1的規(guī)則,那么當(dāng)且僅當(dāng)來自 caller1 對(duì) NodeA 的請(qǐng)求才會(huì)觸發(fā)流量控制。
-
other:表示針對(duì)除 {some_origin_name} 以外的其余調(diào)用方的流量進(jìn)行流量控制。例如,資源NodeA配置了一條針對(duì)調(diào)用者 caller1 的限流規(guī)則,同時(shí)又配置了一條調(diào)用者為 other 的規(guī)則,那么任意來自非 caller1 對(duì) NodeA 的調(diào)用,都不能超過 other 這條規(guī)則定義的閾值。
同一個(gè)資源名可以配置多條規(guī)則,規(guī)則的生效順序?yàn)?#xff1a;
{some_origin_name} > other > default
根據(jù)調(diào)用鏈路入口限流:鏈路限流
NodeSelectorSlot 中記錄了資源之間的調(diào)用鏈路,這些資源通過調(diào)用關(guān)系,相互之間構(gòu)成一棵調(diào)用樹。這棵樹的根節(jié)點(diǎn)是一個(gè)名字為 machine-root 的虛擬節(jié)點(diǎn),調(diào)用鏈的入口都是這個(gè)虛節(jié)點(diǎn)的子節(jié)點(diǎn)。
一棵典型的調(diào)用樹如下圖所示:
machine-root/ \/ \Entrance1 Entrance2/ \/ \DefaultNode(nodeA) DefaultNode(nodeA)上圖中來自入口 Entrance1 和 Entrance2 的請(qǐng)求都調(diào)用到了資源 NodeA,Sentinel 允許只根據(jù)某個(gè)入口的統(tǒng)計(jì)信息對(duì)資源限流。比如我們可以設(shè)置 FlowRule.strategy 為 RuleConstant.CHAIN,同時(shí)設(shè)置 FlowRule.ref_identity 為 Entrance1 來表示只有從入口 Entrance1 的調(diào)用才會(huì)記錄到 NodeA 的限流統(tǒng)計(jì)當(dāng)中,而對(duì)來自 Entrance2 的調(diào)用漠不關(guān)心。
調(diào)用鏈的入口是通過 API 方法 ContextUtil.enter(name) 定義的。
具有關(guān)系的資源流量控制:關(guān)聯(lián)流量控制
當(dāng)兩個(gè)資源之間具有資源爭(zhēng)搶或者依賴關(guān)系的時(shí)候,這兩個(gè)資源便具有了關(guān)聯(lián)。比如對(duì)數(shù)據(jù)庫(kù)同一個(gè)字段的讀操作和寫操作存在爭(zhēng)搶,讀的速度過高會(huì)影響寫得速度,寫的速度過高會(huì)影響讀的速度。如果放任讀寫操作爭(zhēng)搶資源,則爭(zhēng)搶本身帶來的開銷會(huì)降低整體的吞吐量。可使用關(guān)聯(lián)限流來避免具有關(guān)聯(lián)關(guān)系的資源之間過度的爭(zhēng)搶,舉例來說,read_db 和 write_db 這兩個(gè)資源分別代表數(shù)據(jù)庫(kù)讀寫,我們可以給 read_db 設(shè)置限流規(guī)則來達(dá)到寫優(yōu)先的目的:設(shè)置 FlowRule.strategy 為 RuleConstant.RELATE 同時(shí)設(shè)置 FlowRule.ref_identity 為 write_db。這樣當(dāng)寫庫(kù)操作過于頻繁時(shí),讀數(shù)據(jù)的請(qǐng)求會(huì)被限流。
總結(jié)
以上是生活随笔為你收集整理的流量控制理论与Sentinel的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下Mysql5.5的Cmake
- 下一篇: 2008服务器系统开启ftp,win 2