這次阿里編程之夏,我選擇的issue是對(duì)Sentinel做自適應(yīng)流控(參考 #748),以下是最近這一個(gè)月的一些工作匯總,尤其是在自適應(yīng)流控的想法上做了很多方面的探索贷屎,也歡迎大家思考和討論。
一黍判、在CommonFilter
中支持對(duì)無(wú)需限流的網(wǎng)址的過(guò)濾
相關(guān)issue
解決了issue #287:
應(yīng)用中的某些url不需要進(jìn)行統(tǒng)計(jì)豫尽,比如spring boot 端點(diǎn)請(qǐng)求信息,能否增加相關(guān)的擴(kuò)展點(diǎn)顷帖,可以過(guò)濾掉不想統(tǒng)計(jì)的url美旧。
解決方法
由于已經(jīng)有UrlCleaner
接口,我們可以重用該接口并改進(jìn)使用UrlCleaner
統(tǒng)一資源名稱的邏輯贬墩。如果開(kāi)發(fā)人員要排除某些URL榴嗅,他們可以在其UrlCleaner
實(shí)現(xiàn)中將URL轉(zhuǎn)換為空字符串“” ,并且CommonFilter
我們可以檢查已清理的資源名稱是否為空陶舞。如果它是空的嗽测,那么它應(yīng)該被排除,不會(huì)通過(guò)Sentinel的邏輯SphU.entry
。
驗(yàn)證方法
我們可以通過(guò)ClusterBuilderSlot.getClusterNode(res)
方法獲取資源的統(tǒng)計(jì)節(jié)點(diǎn)唠粥,如果ClusterNode
目標(biāo)URL為空疏魏,那么我們認(rèn)為它已被排除。
其他
在開(kāi)源社區(qū)Sentinel中初次提交PR晤愧,更加熟悉了操作流程大莫。
二、自適應(yīng)限流的探索
在探索自適應(yīng)限流的方法時(shí)官份,先學(xué)習(xí)了一些TCP擁塞控制的思路只厘。并且還學(xué)習(xí)了控制的相關(guān)內(nèi)容,如PID控制器舅巷。
1.并發(fā)限制算法Concurrency-limits
(1) TCP擁塞控制算法
gradient = ( RTTnoload / RTTactual )
newLimit = currentLimit × gradient + queueSize
該算法查看最小延遲之間的比率(表示沒(méi)有排隊(duì)最佳情況場(chǎng)景)以及時(shí)間采樣延遲測(cè)量羔味,作為確定隊(duì)列已形成并導(dǎo)致延遲增加的代理。這個(gè)比率給出了延遲變化的梯度gradient钠右。
值為1表示沒(méi)有排隊(duì)赋元,可以增加限制,小于1的值表示已形成過(guò)多的隊(duì)列飒房,應(yīng)降低限制们陆。對(duì)于每個(gè)新樣本,使用這個(gè)比率來(lái)調(diào)整限制情屹,并用簡(jiǎn)單的公式添加允許隊(duì)列的大小。
(2) Concurrency-limits
實(shí)現(xiàn)并集成來(lái)自TCP擁塞控制的概念杂腰,以自動(dòng)檢測(cè)服務(wù)的并發(fā)限制垃你,以便以最佳延遲實(shí)現(xiàn)最佳吞吐量。
不應(yīng)該考慮RPS喂很,而應(yīng)該考慮并發(fā)請(qǐng)求惜颇,我們應(yīng)用排隊(duì)論來(lái)確定服務(wù)在隊(duì)列開(kāi)始建立之前可以處理的并發(fā)請(qǐng)求數(shù),延遲增加少辣,服務(wù)最終耗盡限制凌摄,如CPU,內(nèi)存漓帅,磁盤或網(wǎng)絡(luò)锨亏。
Limit = Average RPS * Average Latency
并發(fā)限制算法,根據(jù)當(dāng)前平均RTT的變化梯度和長(zhǎng)期指數(shù)平滑平均RTT調(diào)整限制忙干。與傳統(tǒng)的擁塞控制算法不同器予,使用平均值而不是最小值。
- 在各種因素的影響下(例如非同質(zhì)請(qǐng)求處理復(fù)雜性以及數(shù)據(jù)大小的廣泛分布)捐迫,RPC方法可能是非常突發(fā)的乾翔。
- 使用最小值還會(huì)導(dǎo)致偏向于不切實(shí)際的低基RTT,從而導(dǎo)致過(guò)度的負(fù)載減少施戴。
指數(shù)衰減方法用在基準(zhǔn)RTT上反浓,以使值保持穩(wěn)定萌丈,可以適應(yīng)于有延遲的特性長(zhǎng)期變化的場(chǎng)景。
核心算法:
//計(jì)算限制范圍[0.5,1.0]的梯度以過(guò)濾異常值
gradient = max(0.5, min(1.0, longtermRtt / currentRtt));
//通過(guò)應(yīng)用漸變并允許某些排隊(duì)來(lái)計(jì)算新限制
newLimit = gradient currentLimit + queueSize;
//使用平滑因子更新限制(默認(rèn)值為0.2)
newLimit = currentLimit (1-smoothing) + newLimit smoothing;
Limit
可能的三種主要狀態(tài):
-
穩(wěn)態(tài)
在這種狀態(tài)下雷则,平均RTT非常穩(wěn)定辆雾,當(dāng)前測(cè)量值在這個(gè)值附近徘徊,Limit
有時(shí)會(huì)降低巧婶,有時(shí)會(huì)增加乾颁。
限制的請(qǐng)求數(shù)趨于穩(wěn)定 從穩(wěn)態(tài)到負(fù)載狀態(tài)
在這種狀態(tài)下,RPS和延遲都會(huì)飆升艺栈。由于系統(tǒng)無(wú)法處理的請(qǐng)求隊(duì)列不斷增長(zhǎng)英岭,因此梯度小于 1.0。低Limit
導(dǎo)致過(guò)多的請(qǐng)求和拒絕數(shù)湿右。通過(guò)指數(shù)衰減诅妹,基準(zhǔn)RTT增長(zhǎng),但會(huì)比當(dāng)前測(cè)量滯后毅人,因此梯度保持在小于1.0吭狡,和低Limit
水平。
.從負(fù)載狀態(tài)到穩(wěn)態(tài)
在這種狀態(tài)下丈莺,系統(tǒng)在長(zhǎng)時(shí)間過(guò)載后會(huì)恢復(fù)穩(wěn)定狀態(tài)划煮。請(qǐng)求不會(huì)被拒絕,取樣到的RTT仍然很低缔俄。在此狀態(tài)期間弛秋,longtermRtt
可能需要一些時(shí)間才能恢復(fù)正常,并且可能比currentRtt
高幾倍俐载。
總結(jié)
此方法對(duì)擁塞控制方法的RTTnoload
和newLimit
進(jìn)行了新的探索和改進(jìn)蟹略。對(duì)Limit
做減半處理,是為了避免高負(fù)載情況的RTT導(dǎo)致的Limit
急劇上升遏佣。
但為了避免Limit
過(guò)低挖炬,不能讓它低于queueSize
。
(3) Concurrency-limits公式中用到的相關(guān)概念與Sentinel的對(duì)比
對(duì)比項(xiàng) | Concurrency-limits | Sentinel |
---|---|---|
因變量 | RTT(連接往返時(shí)間) | ① RT(響應(yīng)時(shí)間) |
自變量 | limit(并發(fā)量) | ② |
隊(duì)列大小 | queueSize | ③ |
(標(biāo)號(hào)的具體內(nèi)容將在算法實(shí)現(xiàn)部分討論)
2.TCP BBR
首先此處回顧下?lián)砣刂艬BR算法:
記中間的拐點(diǎn)為A状婶。在A點(diǎn)以后意敛,數(shù)據(jù)包開(kāi)始排隊(duì),A點(diǎn)處有著最大的帶寬和最小的RTT膛虫。
之所以在此節(jié)提TCP BBR空闲,是因?yàn)榛卣{(diào)洪峰的處理后的圖像,可以和TCP BBR很相似走敌。在回調(diào)洪峰到來(lái)之前和到來(lái)之后碴倾,其實(shí)大致趨勢(shì)也可以是類似圖像。只不過(guò)縱坐標(biāo)的RTT改為響應(yīng)時(shí)間RT,橫坐標(biāo)的BDP改為請(qǐng)求超時(shí)前跌榔,漏桶所處理的容量异雁。
但這里我們要探討一下TCP的擁塞控制和流控的區(qū)別。
它們的場(chǎng)景其實(shí)是完全不同的:
- 對(duì)擁塞控制而言僧须,發(fā)送方可以通過(guò)ACK來(lái)控制速率纲刀;
- 對(duì)流控而言,發(fā)送方不可控制。
簡(jiǎn)單舉例,對(duì)TCP而言惶看,你可以對(duì)發(fā)送方說(shuō):我們處理不了這么快,你們發(fā)慢點(diǎn)面褐。但在流控時(shí),你不能對(duì)用戶說(shuō):雙十一訂單太多了取胎,你少買點(diǎn)吧展哭。
所以,對(duì)TCP來(lái)說(shuō)闻蛀,處理不了的只能先放到隊(duì)列里匪傍,RTT的增大是一種被動(dòng)行為。但是對(duì)流控回調(diào)洪峰場(chǎng)景來(lái)說(shuō)觉痛,你等到系統(tǒng)崩掉就晚了役衡,因此在必要的時(shí)候必須引入勻速器,致使RT增加薪棒。在這里映挂,為了保護(hù)系統(tǒng),RT的增加是一種主動(dòng)行為盗尸。
因此對(duì)TCP BBR來(lái)說(shuō),最優(yōu)解處就是中間的拐點(diǎn)帽撑,畢竟發(fā)再快了也只是多占用緩存空間泼各,不能再加快處理速度。對(duì)流控而言亏拉,拿回調(diào)洪峰舉例扣蜻,最重要的目的則是“削峰填谷”,這一秒不能同時(shí)處理那么多及塘,就放到下一秒處理莽使,只要這類請(qǐng)求允許一定的延遲,那就沒(méi)必要當(dāng)下全部處理掉笙僚,把收斂點(diǎn)放后面些也沒(méi)事芳肌。這樣也有利于讓更多系統(tǒng)資源抽身去處理其他的“洪峰”。
3.PID控制器思路
在提到PID控制器之前,先說(shuō)下兩種編程方式:命令式和聲明式亿笤。
- 命令式編程:命令“機(jī)器”如何去做事情(how)翎迁,這樣不管你想要的是什么(what),它都會(huì)按照你的命令實(shí)現(xiàn)净薛。
- 聲明式編程:告訴“機(jī)器”你想要的是什么(what)汪榔,讓機(jī)器想出如何去做(how)。
而自適應(yīng)的限流應(yīng)該適合“聲明式編程”的設(shè)計(jì)肃拜,告訴Sentinel系統(tǒng)應(yīng)該達(dá)到什么狀態(tài)痴腌,由系統(tǒng)自己調(diào)節(jié)。
因此燃领,PID控制器的思想其實(shí)是契合的士聪。
反饋理論的要素包括三個(gè)部分:測(cè)量、比較和執(zhí)行柿菩。測(cè)量關(guān)鍵的是被控變量的實(shí)際值戚嗅,與期望值相比較,用這個(gè)偏差來(lái)糾正系統(tǒng)的響應(yīng)枢舶,執(zhí)行調(diào)節(jié)控制懦胞。
(1) PID算法基本原理
PID算法的執(zhí)行流程是非常簡(jiǎn)單的,即利用反饋來(lái)檢測(cè)偏差信號(hào)凉泄,并通過(guò)偏差信號(hào)來(lái)控制被控量躏尉。而控制器本身就是比例、積分后众、微分三個(gè)環(huán)節(jié)的加和胀糜。其功能框圖如下:
根據(jù)上圖我們考慮在某個(gè)特定的時(shí)刻t,此時(shí)輸入量為rin(t)蒂誉,輸出量為rout(t)教藻,于是偏差就可計(jì)算為err(t)=rin(t)-rout(t)。于是PID的基本控制規(guī)律就可以表示為如下公式:
其中Kp為比例帶右锨,TI為積分時(shí)間括堤,TD為微分時(shí)間。PID控制的基本原理就是如此绍移。
(2) PID算法的離散化
上面簡(jiǎn)單介紹了PID算法的基本原理悄窃,但要在計(jì)算機(jī)上實(shí)現(xiàn)就必須將其離散化,接下來(lái)我們就說(shuō)一說(shuō)PID算法的離散化問(wèn)題蹂窖。在實(shí)現(xiàn)離散化之前轧抗,我們需要對(duì)比例、積分瞬测、微分的特性做一個(gè)簡(jiǎn)單的說(shuō)明横媚。
比例就是用來(lái)對(duì)系統(tǒng)的偏差進(jìn)行反應(yīng)纠炮,所以只要存在偏差,比例就會(huì)起作用分唾。積分主要是用來(lái)消除靜差抗碰,所謂靜差就是指系統(tǒng)穩(wěn)定后輸入輸出之間依然存在的差值,而積分就是通過(guò)偏差的累計(jì)來(lái)抵消系統(tǒng)的靜差绽乔。而微分則是對(duì)偏差的變化趨勢(shì)做出反應(yīng)弧蝇,根據(jù)偏差的變化趨勢(shì)實(shí)現(xiàn)超前調(diào)節(jié),提高反應(yīng)速度折砸。
在實(shí)現(xiàn)離散前看疗,我們假設(shè)系統(tǒng)采樣周期為T。假設(shè)我們檢查第K個(gè)采樣周期睦授,很顯然系統(tǒng)進(jìn)行第K次采樣两芳。此時(shí)的偏差可以表示為err(K)=rin(K)-rout(K),那么積分就可以表示為:err(K)+ err(K+1)+┈┈去枷,而微分就可以表示為:(err(K)- err(K-1))/T怖辆。于是我們可以將第K次采樣時(shí),PID算法的離線形式表示為:
也可以記為:
三删顶、自適應(yīng)限流算法的實(shí)現(xiàn)
在這個(gè)月對(duì)自適應(yīng)限流算法的實(shí)現(xiàn)時(shí)竖螃,其實(shí)也大致是按照上述探索流程一步步實(shí)現(xiàn)。針對(duì)限流場(chǎng)景逗余,實(shí)現(xiàn)了比較經(jīng)典的用戶洪峰場(chǎng)景和回調(diào)洪峰場(chǎng)景特咆。
1.用戶洪峰
(1) 參考cocurrency-limits的實(shí)現(xiàn)
概述
在流量控制場(chǎng)景中我們會(huì)經(jīng)常遇到流量洪峰的情況。例如雙十一零點(diǎn)的情況录粱,但這種場(chǎng)景又盡量不能有太長(zhǎng)的延時(shí)腻格。因此令牌桶限流是解決這種場(chǎng)景的流量洪峰的處理方法。這種洪峰我們一般稱作用戶洪峰啥繁。
用戶洪峰需要考慮的因素:
- 允許訪問(wèn)的速率:令牌發(fā)放的速度r
- 系統(tǒng)承受的最大洪峰:當(dāng)令牌桶滿的時(shí)候菜职,洪峰到達(dá),這時(shí)候應(yīng)用承受最大的QPS沖擊 = 桶的容量 + 該秒令牌桶發(fā)放的速度r
- 洪峰爆發(fā)的間隔時(shí)間:下一次洪峰爆發(fā)前旗闽,盡量填滿令牌桶
而如果想做到自適應(yīng)的處理酬核,與往常開(kāi)發(fā)者設(shè)置這些限流指標(biāo)不同,我們要做到用開(kāi)發(fā)者的期望指標(biāo)來(lái)代替宪睹。如期望的RT、吞吐量等蚕钦。
在開(kāi)發(fā)中亭病,主要的考慮是通過(guò)用戶期望RT和通過(guò)比率來(lái)調(diào)節(jié)令牌發(fā)放速度;根據(jù)往常最大的請(qǐng)求數(shù)和令牌桶速率調(diào)節(jié)令牌桶容量嘶居。
核心算法如下:
// 計(jì)算限制范圍[1.0, 5.0]的梯度
// 實(shí)際通過(guò)率越小罪帖,梯度值越大促煮,以增加后續(xù)通過(guò)數(shù)
double gradientRatio = Math.max(1.0, Math.min(2.0, targetRatio / ratio));
// 計(jì)算限制范圍[0.5, 1.0]的梯度以過(guò)濾異常值
// 實(shí)際 avgRt 越大,梯度值越小整袁,說(shuō)明需要限制通過(guò)數(shù)
double needRt = Math.min(longTermRt, expectRt);
gradientRt = Math.max(0.5, Math.min(1.0, needRt / avgRt));
// 最后的令牌發(fā)放速度由通過(guò)率和 Rt 共同決定
newCount = (long)(gradientRatio * gradientRt * currentCount);
// 使用平滑因子更新令牌發(fā)放速度(默認(rèn)為0.2)
newCount = (long)(currentCount * (1 - smoothing) + newCount * smoothing);
// 計(jì)算令牌桶最大容量
long newMaxToken = Math.max(newCount, (long)(previousTotalQps * targetRatio));
long oldMaxToken = maxTokens.get();
if (newMaxToken > oldMaxToken) { maxTokens.compareAndSet(oldMaxToken, newMaxToken);
}
Demo示例
AdaptiveDemo
演示了如何使用自適應(yīng)限流算法菠齿。
-
AdaptiveRule()
通過(guò)設(shè)置下列參數(shù),構(gòu)建了一個(gè)流控規(guī)則:
AdaptiveRule rule = new AdaptiveRule();rule.setResource(KEY);
rule.setTargetRatio(0.5);
rule.setExpectRt(0.5);
其中坐昙,設(shè)置目標(biāo)通過(guò)50%的請(qǐng)求绳匀,目標(biāo)的RT不超過(guò)0.5。
-
StableTask()
是模擬小流量的情況炸客。 -
RunTask1()
和RunTask2()
是模擬了兩段大流量的情況疾棵。 - 觀察輸出:
85 send qps is: 5
1564124570560, total:5, pass:5, block:0
84 send qps is: 2
1564124571560, total:2, pass:2, block:0
83 send qps is: 1
1564124572561, total:1, pass:1, block:0
82 send qps is: 8
1564124573560, total:8, pass:8, block:0
81 send qps is: 1
1564124574561, total:1, pass:1, block:0
80 send qps is: 56850
1564124575596, total:56850, pass:6111, block:50739
79 send qps is: 131744
1564124576597, total:131744, pass:17604, block:114140
78 send qps is: 138365
1564124577597, total:138365, pass:21124, block:117241
77 send qps is: 141735
1564124578597, total:141735, pass:25349, block:116386
76 send qps is: 141881
1564124579599, total:141881, pass:30417, block:111464
75 send qps is: 142156
1564124580600, total:142156, pass:32622, block:109534
74 send qps is: 143874
1564124581600, total:143874, pass:39146, block:104728
73 send qps is: 145346
1564124582599, total:145346, pass:39147, block:106199
72 send qps is: 142118
1564124583601, total:142118, pass:46975, block:95144
71 send qps is: 146782
1564124584602, total:146782, pass:56357, block:90424
70 send qps is: 149184
1564124585604, total:149184, pass:67627, block:81557
可以看到從第 80 秒開(kāi)始,大流量到達(dá)痹仙,允許通過(guò)的數(shù)量逐漸在接近用戶的目標(biāo)是尔。
45 send qps is: 3
1564124610616, total:3, pass:3, block:0
44 send qps is: 3
1564124611616, total:3, pass:3, block:0
43 send qps is: 3
1564124612616, total:3, pass:3, block:0
42 send qps is: 2
1564124613617, total:2, pass:2, block:0
41 send qps is: 3
1564124614618, total:3, pass:3, block:0
40 send qps is: 122091
1564124615619, total:122091, pass:60573, block:61518
39 send qps is: 141463
1564124616619, total:141463, pass:50784, block:90680
38 send qps is: 145550
1564124617620, total:145550, pass:58280, block:87270
37 send qps is: 141654
1564124618619, total:141654, pass:69462, block:72191
36 send qps is: 146492
1564124619619, total:146492, pass:84673, block:61819
后面模擬了第二段大流量的到來(lái),可以看到由于在第一次大流量到來(lái)時(shí)計(jì)算了比較準(zhǔn)確的桶的容量开仰,因此在第 40 秒剛剛到來(lái)大流量時(shí)拟枚,就已經(jīng)可以滿足用戶制定的 50% 通過(guò)率的目標(biāo)。
而大流量突然的到來(lái)會(huì)導(dǎo)致一瞬間的RT超過(guò)用戶需求的 0.5 的值众弓,因此在 40 s以后的通過(guò)率為了滿足RT的需求有所降低恩溅,但后面系統(tǒng)穩(wěn)定后又開(kāi)始逐步提升通過(guò)率。
(2) 參考PID控制器的算法實(shí)現(xiàn)(未完成調(diào)參)
// 根據(jù)PID控制器算法田轧,控制令牌桶發(fā)放令牌的速率
protected long syncCountByPid(ClusterNode node, double expectRt) {
// 參數(shù)初始化
double Kp = 1000, Ki =5, Kd = 0;
// 把穩(wěn)定用戶設(shè)定的Rt作為目標(biāo)
double errNum = expectRt - node.avgRt();
// 每次積分值暴匠、差值的計(jì)算必須是線程安全的,但只有AtomicLong類型
// 沒(méi)有相應(yīng)double類型傻粘,因此需要將double和long類型互轉(zhuǎn)
err.compareAndSet(err.get(), Double.doubleToLongBits(errNum));
double integralNum = Double.longBitsToDouble(integral.get()) + errNum;
integral.compareAndSet(integral.get(), Double.doubleToLongBits(integralNum));
double countNum = Kp * errNum + Ki * integralNum + Kd * (errNum - Double.longBitsToDouble(err_last.get()));
err_last.compareAndSet(err_last.get(), Double.doubleToLongBits(errNum));
return (long)countNum;
}
但為了得到更好的表現(xiàn)每窖,還需要進(jìn)一步調(diào)參。
2.回調(diào)洪峰
參考TCP-BBR的流控算法設(shè)計(jì)
這種方法還沒(méi)有具體實(shí)現(xiàn)弦悉,因?yàn)榘l(fā)現(xiàn)了一些問(wèn)題窒典,而且與cocurrency-limits都屬于對(duì)TCP擁塞控制算法的思想借鑒。因此在實(shí)現(xiàn)了上一種方法后稽莉,預(yù)計(jì)先實(shí)現(xiàn)PID控制器思路瀑志,如PID控制器思路的可行性低于TCP擁塞控制思路,再去著手借鑒TCP-BBR算法嘗試效果污秆。
這里可以先把設(shè)計(jì)的算法和遇到的問(wèn)題一并解說(shuō)劈猪。設(shè)計(jì)的算法如下:
-
啟動(dòng)階段與穩(wěn)定階段
這個(gè)階段可以根據(jù)TCP BBR算法,根據(jù)實(shí)際系統(tǒng)情況良拼,不斷調(diào)節(jié)增益系數(shù)战得,來(lái)計(jì)算處理速率。TCP BBR算法流程圖示如下:
TCPBBR算法流程圖.png那么啟動(dòng)與穩(wěn)定階段的算法流程也可類似設(shè)計(jì):
流控流程圖.jpg啟動(dòng)階段的增益系數(shù)G庸推,TCP BBR算法為
常侦,是根據(jù)
做擬合得到浇冰,那么在流控場(chǎng)景中的增益系數(shù),也可以根據(jù)CPU使用率的情況做擬合聋亡。
啟動(dòng)階段過(guò)后的穩(wěn)定階段:
- 若CPU使用率未達(dá)到規(guī)定上限肘习,也全部通過(guò),則說(shuō)明此階段流量水位低坡倔。
- 若CPU使用率已達(dá)到規(guī)定上限漂佩,則QPS閾值已達(dá)到,設(shè)為
致讥。當(dāng)然仅仆,針對(duì)回調(diào)洪峰場(chǎng)景而言,在洪峰到來(lái)之前普遍流量水位偏低垢袱,這種情況很少達(dá)到墓拜。
-
回調(diào)洪峰階段
此時(shí)若判斷為回調(diào)洪峰,開(kāi)始勻速器模式请契。根據(jù)請(qǐng)求允許的最大延時(shí)咳榜,以及洪峰的請(qǐng)求量
,計(jì)算
爽锥。
- 若之前CPU使用率未達(dá)到規(guī)定上限涌韩,則先要根據(jù)增益系數(shù)G不斷向上調(diào),
- 當(dāng)
時(shí)氯夷,CPU使用率仍未到上限臣樱,則可以按照
作為漏桶速度;
- 當(dāng)
且
時(shí)腮考,說(shuō)明已達(dá)到CPU使用率上限雇毫,漏桶速度最大只能為
。
- 當(dāng)
- 若之前CPU使用率已達(dá)到規(guī)定上限踩蔚,則漏桶速度最大為
棚放。
- 若之前CPU使用率未達(dá)到規(guī)定上限涌韩,則先要根據(jù)增益系數(shù)G不斷向上調(diào),
遇到要思考的問(wèn)題如下:
原計(jì)劃是計(jì)算洪峰請(qǐng)求量的大小requestQps
,然后根據(jù)用戶設(shè)置的maxRt
來(lái)計(jì)算count馅闽,但是后來(lái)發(fā)現(xiàn)難以統(tǒng)計(jì)飘蚯。首先,這個(gè)請(qǐng)求量一定不可能是讓用戶來(lái)設(shè)定福也,大多數(shù)場(chǎng)景下用戶也不知道請(qǐng)求量會(huì)有多少局骤。其次,如何界定“突發(fā)”的標(biāo)準(zhǔn)也是一個(gè)問(wèn)題暴凑,是算20ms內(nèi)的請(qǐng)求數(shù)算突發(fā)流量峦甩,還是50ms,100ms……搬设?
假設(shè)周期標(biāo)準(zhǔn)可以定下來(lái)穴店,算出了第一個(gè)周期的request
,那么第二個(gè)周期又到來(lái)了一波流量拿穴,第二個(gè)周期的request
是不是要加上上個(gè)周期的流量泣洞,直到這幾個(gè)周期加起來(lái)是1s才能算出requestQps
。但這個(gè)計(jì)算的時(shí)間又會(huì)導(dǎo)致請(qǐng)求一直在等待默色,浪費(fèi)了一定的時(shí)間球凰。
或者用每個(gè)周期的request
估算requestQps
,但又會(huì)造成這個(gè)估計(jì)極大的不準(zhǔn)確腿宰。
因此呕诉,若想使用這個(gè)方法來(lái)做回調(diào)洪峰場(chǎng)景的自適應(yīng)流控,可能還需要進(jìn)一步的設(shè)計(jì)吃度,或徹底改變之前的流控check實(shí)現(xiàn)方式甩挫,引入隊(duì)列等等。
與用戶洪峰對(duì)應(yīng)的令牌桶方法不同的是椿每,不能通過(guò)觀察Rt的變化來(lái)判斷閾值伊者,因?yàn)樵趧蛩倥抨?duì)方法下,排隊(duì)時(shí)間占總Rt的大部分间护,無(wú)法衡量系統(tǒng)情況亦渗。
目前的先實(shí)現(xiàn)了一個(gè)比較簡(jiǎn)單的方法,如果發(fā)現(xiàn)超時(shí)情況就對(duì)count
(閾值)加倍,直到cpuUsage
不符合要求汁尺。
以上就是這個(gè)月所做探索的一些思考和總結(jié)法精,下個(gè)月會(huì)繼續(xù)自適應(yīng)限流算法的優(yōu)化,如有更新的思路痴突,歡迎大家一起討論搂蜓。