服務治理通常是指通過限流、熔斷等手段,保障微服務的可靠運行,即運行時治理。更加寬泛的服務治理還包括微服務持續(xù)集成(開源軟件管理、自動化測試等),微服務部署最佳實踐(滾動升級、灰度發(fā)布等),微服務可觀測性能力(日志、監(jiān)控、告警等)構(gòu)建等。
??微服務治理專題主要探討運行時治理。隔離倉是適用于大部分故障模式,簡單有效的治理策略,本章介紹隔離倉的原理和作用。
隔離倉的定義和作用
??業(yè)務請求的處理都會占用系統(tǒng)資源,包括CPU、內(nèi)存、線程池、連接池等。隔離倉是一種限制業(yè)務請求對系統(tǒng)資源占用的服務治理策略,防止單個業(yè)務請求或者單個微服務實例過多的占用系統(tǒng)資源,對其他業(yè)務請求以及系統(tǒng)總體的性能產(chǎn)生嚴重影響。
??線程池是治理策略應用最廣泛的系統(tǒng)資源,通常所有請求都在一個共享的線程池處理,常見的隔離倉實現(xiàn),都是限制請求對線程池的過多占用。本文以 Spring Cloud Huawei 為例,演示其隔離倉在兩種故障場景下的作用。
- 場景一
??微服務A調(diào)用微服務B,A和B分別有M個實例,模擬N個并發(fā)客戶端連續(xù)不斷的請求A。然后給B擴容1個實例。觀察應用治理策略和不應用策略的情況下,時延和TPS的變化情況。
- 場景二
??微服務A調(diào)用微服務B,A和B分別有M個實例,B有兩個接口 X 和 Y, 其中X處理100ms,Y處理500 ms,模擬N 個并發(fā)客戶端通過A連續(xù)請求X接口,N 個并發(fā)客戶端通過A連續(xù)請求Y接口。觀察應用治理策略和不應用策略的情況下,時延和TPS的變化情況。
Spring Cloud Huawei客戶端隔離倉的工作原理和效果
??Spring Cloud Huawei 客戶端隔離倉 的主要作用是限制一個實例、或者一個實例的某個接口最大并發(fā)數(shù),當一個實例的最大并發(fā)處理大于設置的閾值maxConcurrentCalls的時候,后續(xù)請求會在當前線程等待maxWaitDuration時間,如果這段時間有請求處理完畢,那么后續(xù)請求會繼續(xù)處理,否則就會被丟棄,返回408錯誤。
??Spring Cloud Huawei 服務端隔離倉 的主要作用是限制一個接口的最大并發(fā)數(shù),當一個接口的最大并發(fā)處理大于設置的閾值maxConcurrentCalls的時候,后續(xù)請求會在當前線程等待maxWaitDuration時間,如果這段時間有請求處理完畢,那么后續(xù)請求會繼續(xù)處理,否則就會被丟棄,返回408錯誤。
- 場景一
??微服務A的隔離倉配置:
servicecomb:
matchGroup:
allOperation: |
matches:
- apiPath:
prefix: "/"
instanceBulkhead:
## 隔離倉限制正在處理的請求數(shù)為20個,新來的請求等待1000毫秒沒有獲取到
## 許可,將被拒絕。
allOperation: |
maxConcurrentCalls: 20
maxWaitDuration: 1000
為了匹配測試用例,設置微服務A的線程池大小為20
server:
tomcat:
threads:
max: 20
minSpare: 20
??微服務A調(diào)用微服務B,A和B分別有1個實例,模擬40個并發(fā)客戶端連續(xù)不斷的請求A。然后給B擴容1個實例。觀察應用治理策略和不應用策略的情況下,時延和TPS的變化情況。
測試結(jié)果:
不使用隔離倉:
Total time:121852
Success count:200000
Timeout count:0
Error count:0
Average Latency:24
|(10,7942)||(20,90667)||(50,93017)||(100,7041)||(200,1151)||(500,173)||(1000,9)|
使用隔離倉:
Total time:112440
Success count:200000
Timeout count:0
Error count:0
Average Latency:22
|(10,8683)||(20,100275)||(50,86137)||(100,4106)||(200,679)||(500,120)||(1000,0)|
??從上述結(jié)果可以看出使用隔離倉的情況下,時延大于200ms的請求明顯減少。 這個結(jié)果說明隔離倉的使用并沒有降低系統(tǒng)的處理性能,甚至可能帶來一些性能的改善,減少時延偏差較大的請求數(shù)量。上述測試場景,并沒有演示新啟動實例導致故障的場景。如果需要模擬這種場景,可以考慮微服務A部署10個實例,并且采用500個并發(fā)客戶端訪問。
- 場景二
微服務A的隔離倉配置:
servicecomb:
matchGroup:
allOperation: |
matches:
- apiPath:
# 對耗時的接口配置隔離倉
prefix: "/benchmark/delay/z100"
instanceBulkhead:
## 隔離倉限制正在處理的請求數(shù)為20個,新來的請求等待1000毫秒沒有獲取到
## 許可,將被拒絕。
allOperation: |
maxConcurrentCalls: 20
maxWaitDuration: 1000
# 為了匹配測試用例,設置微服務A的線程池大小為40
server:
tomcat:
threads:
max: 40
minSpare: 40
??微服務A調(diào)用微服務B,A和B分別有1個實例,B有兩個接口 X 和 Y, 其中X處理1ms,Y處理100 ms,模擬20 個并發(fā)客戶端通過A連續(xù)請求X接口,20 個并發(fā)客戶端通過A連續(xù)請求Y接口。觀察應用治理策略和不應用策略的情況下,時延和TPS的變化情況。
測試結(jié)果:
不使用隔離倉:
Total time:69029
Success count:40000
Timeout count:0
Error count:0
Average Latency:68
|(10,2175)||(20,12078)||(50,5727)||(100,17)||(200,20003)||(500,0)||(1000,0)||(10000,0)|
使用隔離倉:
Total time:107354
Success count:40000
Timeout count:0
Error count:0
Average Latency:106
|(10,2217)||(20,14264)||(50,3506)||(100,7)||(200,15738)||(500,4268)||(1000,0)||(10000,0)|
??從上述結(jié)果可以看出使用隔離倉的情況下,時延小于20ms的請求有所增加,但是時延超過500ms的請求增加更加明顯。這是因為測試場景屬于IO密集型場景,使用隔離倉,降低了Y接口的并發(fā)度,大量請求排隊,導致整體的時延大幅增長。下面把客戶端隔離倉去掉,改為服務端隔離倉,再看看效果。
微服務B的隔離倉配置:
servicecomb:
matchGroup:
allOperation: |
matches:
- apiPath:
# 對耗時的接口配置隔離倉
prefix: "/benchmark/delay/z100"
bulkhead:
## 隔離倉限制正在處理的請求數(shù)為20個,新來的請求等待1000毫秒沒有獲取到
## 許可,將被拒絕。
allOperation: |
maxConcurrentCalls: 10
maxWaitDuration: 1000
# 為了匹配測試用例,設置微服務B的線程池大小為20
server:
tomcat:
threads:
max: 20
minSpare: 20
??微服務A調(diào)用微服務B,A和B分別有1個實例,B有兩個接口 X 和 Y, 其中X處理1ms,Y處理100 ms,模擬20 個并發(fā)客戶端通過A連續(xù)請求X接口,20 個并發(fā)客戶端通過A連續(xù)請求Y接口。觀察應用治理策略和不應用策略的情況下,時延和TPS的變化情況。
測試結(jié)果:
不使用隔離倉:
Total time:110685
Success count:40000
Timeout count:0
Error count:0
Average Latency:109
|(10,160)||(20,1207)||(50,4378)||(100,14091)||(200,19906)||(500,258)||(1000,0)||(10000,0)|
使用隔離倉:
Total time:214565
Success count:40000
Timeout count:0
Error count:0
Average Latency:213
|(10,46)||(20,734)||(50,279)||(100,3941)||(200,14972)||(500,19995)||(1000,33)||(10000,0)|
??從上述結(jié)果可以看出使用隔離倉的情況下,平均時延和性能同樣會下降。我們適當調(diào)整下隔離倉的限制,快速丟棄一些請求:
servicecomb:
matchGroup:
allOperation: |
matches:
- apiPath:
# 對耗時的接口配置隔離倉
prefix: "/benchmark/delay/z100"
bulkhead:
## 隔離倉限制正在處理的請求數(shù)為20個,新來的請求等待1000毫秒沒有獲取到
## 許可,將被拒絕。
allOperation: |
maxConcurrentCalls: 10
maxWaitDuration: 10
# 為了匹配測試用例,設置微服務B的線程池大小為20
server:
tomcat:
threads:
max: 20
minSpare: 20
使用隔離倉的測試結(jié)果:
Total time:68189
Success count:22733
Timeout count:1
Error count:17266
Average Latency:115
|(10,53)||(20,2096)||(50,19470)||(100,13025)||(200,3885)||(500,1361)||(1000,109)||(10000,1)|
??上述結(jié)果可以看出,快速丟棄請求的情況下,時延小于50ms的請求大于20000個。隔離倉保證了處理很快的接口能夠得到快速成功執(zhí)行,前提條件是處理很慢的接口不占用資源,快速失敗。
隔離倉總結(jié)
??隔離倉的使用,在計算密集型場景下,對系統(tǒng)的性能影響很小,甚至可以起到一定的性能改善作用。在IO密集型場景下,由于隔離倉降低了請求的并發(fā)執(zhí)行線程,會導致吞吐量降低和時延增加。
??也可以看出,在IO等待比較長的情況下,系統(tǒng)的吞吐量和系統(tǒng)的可靠性是兩個沒法同時滿足的目標,如果要保證成功率不降低,并且吞吐量增加,那么勢必增加業(yè)務線程等系統(tǒng)資源占用,從而對系統(tǒng)整體的可靠性產(chǎn)生影響。對于耗時的請求,只能通過快速丟棄超過資源使用限制的部分,才能夠保證系統(tǒng)吞吐量不下降,并且避免產(chǎn)生系統(tǒng)性的全局功能影響。因此,系統(tǒng)應該合理的設計部分耗時請求的最大并發(fā),在超過這些指標的時候,快速丟棄多余的請求。過度追求耗時請求的吞吐量而擴大線程池、連接池等,是很多應用系統(tǒng)最常見的設計誤區(qū)。
審核編輯 黃宇
-
IO
+關注
關注
0文章
427瀏覽量
38996 -
華為云
+關注
關注
3文章
2385瀏覽量
17191
發(fā)布評論請先 登錄
相關推薦
評論