個人備案經(jīng)營網(wǎng)站優(yōu)化設計三要素
🔥博客主頁:?【小扳_-CSDN博客】
?感謝大家點贊👍收藏?評論?
文章目錄
? ? ? ? 1.0 微服務保護
? ? ? ? 1.1 請求限流方案
? ? ? ? 1.2 線程隔離方案
? ? ? ? 1.3 服務熔斷方案
? ? ? ? 2.0 Sentinel
? ? ? ? 2.1 Sentinel 安裝
? ? ? ? 2.2 微服務整合
? ? ? ? 3.0 Sentinel-請求限流
? ? ? ? 4.0 Sentinel-線程隔離
????????4.1 OpenFeign 整合 Sentinel
????????4.2 配置線程隔離
? ? ? ? 5.0?Sentinel-Fallback
? ? ? ? 6.0 Sentinel-服務熔斷
? ? ? ? 6.1 配置熔斷策略
? ? ? ? 1.0 微服務保護
????????保證服務運行的健壯性,避免級聯(lián)失敗導致的雪崩問題,就屬于微服務保護。
????????微服務保護的方案有很多,比如:
????????????????- 請求限流
????????????????- 線程隔離
????????????????- 服務熔斷
????????這些方案或多或少都會導致服務的體驗上略有下降,比如請求限流,降低了并發(fā)上限;線程
隔離,降低了可用資源數(shù)量;服務熔斷,降低了服務的完整度,部分服務變的不可用或弱可用。因
此這些方案都屬于服務降級的方案。但通過這些方案,服務的健壯性得到了提升。
? ? ? ? 1.1 請求限流方案
????????服務故障最重要原因,就是并發(fā)太高!解決了這個問題,就能避免大部分故障。當然,接口
的并發(fā)不是一直很高,而是突發(fā)的。因此請求限流,就是限制或控制接口訪問的并發(fā)流量,避免服
務因流量激增而出現(xiàn)故障。
? ? ? ? 簡單來說,請求限流往往會有一個限流器,數(shù)量高低起伏的并發(fā)請求曲線,經(jīng)過限流器就變
的非常平穩(wěn)。這就像是水電站的大壩,起到蓄水的作用,可以通過開關控制水流出的大小,讓下游
水流始終維持在一個平穩(wěn)的量。
? ? ? ? PS:QPS 指的是服務器每秒可以處理的請求數(shù)量。
? ? ? ? 1.2 線程隔離方案
????????當一個業(yè)務接口響應時間長,而且并發(fā)高時,就可能耗盡服務器的線程資源,導致服務內(nèi)的
其它接口受到影響。所以我們必須把這種影響降低,或者縮減影響的范圍。線程隔離正是解決這個
問題的好辦法。
線程隔離的思想來自輪船的艙壁模式:
? ? ? ? 簡單來說,就是限制不正常的接口的線程數(shù)量,防止線程資源都用到阻塞的接口從而影響其
他正常接口提供服務。
舉個例子:
????????給查詢購物車業(yè)務限定可用線程數(shù)量上限為 20,這樣即便查詢購物車的請求因為查詢商品服
務而出現(xiàn)故障,也不會導致服務器的線程資源被耗盡,不會影響到其它接口。
? ? ? ? 1.3 服務熔斷方案
????????線程隔離雖然避免了雪崩問題,但故障服務(商品服務)依然會拖慢購物車服務(服務調(diào)用
方)的接口響應速度。而且商品查詢的故障依然會導致查詢購物車功能出現(xiàn)故障,購物車業(yè)務也變
的不可用了。
? ? ? ? 因此可以使用熔斷結(jié)合 Fallback 機制來解決:
? ? ? ? 1)編寫服務降級邏輯:就是服務調(diào)用失敗后的處理邏輯,根據(jù)業(yè)務場景,可以拋出異常,也
可以返回友好提示或默認數(shù)據(jù)。
? ? ? ? 2)異常統(tǒng)計和熔斷:統(tǒng)計服務提供方的異常比例,當比例過高表明該接口會影響到其它服
務,應該拒絕調(diào)用該接口,而是直接走降級邏輯。
? ? ? ? 當發(fā)現(xiàn)異常超過一定的數(shù)量或者慢調(diào)用到達一定的數(shù)量之后,那么就不會選擇繼續(xù)調(diào)用該接
口,而是走 Fallback 降級邏輯路線了。
? ? ? ? 2.0 Sentinel
? ? ? ??Sentinel 是阿里巴巴開源的一款服務保護框架,目前已經(jīng)加入 SpringCloudAlibaba 中。官
方網(wǎng)站:home | Sentinel
Sentinel 的使用可以分為兩個部分:
? ? ? ? 1)核心庫(Jar包):不依賴任何框架/庫,能夠運行于 Java 8 及以上的版本的運行時環(huán)
境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。在項目中引入依賴即可實現(xiàn)服務限
流、隔離、熔斷等功能。
? ? ? ? 2)控制臺(Dashboard):Dashboard 主要負責管理推送規(guī)則、監(jiān)控、管理機器信息等。
? ? ? ? 2.1 Sentinel 安裝
? ? ? ? 1)下載 jar 包:Releases · alibaba/Sentinel · GitHub
? ? ? ? 2)將 jar 包放在任意非中文、不包含特殊字符的目錄下,重命名為 sentinel-
dashboard.jar,然后運行如下命令啟動控制臺:
java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
? ? ? ? 3)訪問 http://localhost:8090 頁面,就可以看到 sentinel 的控制臺了:
需要輸入賬號和密碼,默認都是:sentinel
????????登錄后,即可看到控制臺,默認會監(jiān)控 sentinel-dashboard 服務本身:?
? ? ? ? 2.2 微服務整合
????????連接 sentinel-dashboard 控制臺,步驟如下:
? ? ? ? 1)引入 sentinel 依賴:
<!--sentinel--> <dependency><groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
? ? ? ? 2)配置控制臺:
????????修改 application.yaml 文件,添加下面內(nèi)容:
spring:cloud: sentinel:transport:dashboard: localhost:8090
? ? ? ? 3)訪問任意相關的接口:
? ? ? ? 重啟之后,然后訪問查詢購物車接口,sentinel 的客戶端就會將服務訪問的信息提交到
sentinel-dashboard 控制臺。并展示出統(tǒng)計信息:
點擊簇點鏈路菜單,會看到下面的頁面:
????????所謂簇點鏈路,就是單機調(diào)用鏈路,是一次請求進入服務后經(jīng)過的每一個被 Sentinel 監(jiān)控的
資源。默認情況下,Sentinel 會監(jiān)控 SpringMVC 的每一個 Endpoint(接口)。
????????因此,我們看到 /carts 這個接口路徑就是其中一個簇點,我們可以對其進行限流、熔斷、隔
離等保護措施。
?
????????打開 Sentinel 的請求方式前綴,把請求方式 + 請求路徑作為簇點資源名:
? ? ? ? 添加以下配置:
spring:cloud:sentinel:transport:dashboard: localhost:8090http-method-specify: true # 開啟請求方式前綴
????????然后,重啟服務,通過頁面訪問購物車的相關接口,可以看到 sentinel 控制臺的簇點鏈路發(fā)
生了變化:
? ? ? ? 3.0 Sentinel-請求限流
????????在簇點鏈路后面點擊流控按鈕,即可對其做限流配置:
在彈出的菜單中這樣填寫:
????????這樣就把查詢購物車列表這個簇點資源的流量限制在了每秒 6 個,也就是最大 QPS 為 6 。
利用 Jemeter 做限流測試,我們每秒發(fā)出 10 個請求:
最終監(jiān)控結(jié)果如下:
????????這個接口的通過 QPS 穩(wěn)定在 6 附近,而拒絕的 QPS 在 4 附近,符合我們的預期。
? ? ? ? 4.0 Sentinel-線程隔離
????????限流可以降低服務器壓力,盡量減少因并發(fā)流量引起的服務故障的概率,但并不能完全避免
服務故障。一旦某個服務出現(xiàn)故障,我們必須隔離對這個服務的調(diào)用,避免發(fā)生雪崩。
????????比如,查詢購物車的時候需要查詢商品,為了避免因商品服務出現(xiàn)故障導致購物車服務級聯(lián)
失敗,我們可以把購物車業(yè)務中查詢商品的部分隔離起來,限制可用的線程資源:
????????這樣,即便商品服務出現(xiàn)故障,最多導致查詢購物車業(yè)務故障,并且可用的線程資源也被限
定在一定范圍,不會導致整個購物車服務崩潰。
? ? ? ? 4.1 OpenFeign 整合 Sentinel
? ? ? ? 修改 application.yml 文件,開啟 Feign 的 sentinel 功能:
feign:sentinel:enabled: true # 開啟feign對sentinel的支持
????????需要注意的是,默認情況下 SpringBoot 項目的 tomcat 最大線程數(shù)是 200,允許的最大連接
是 8492,單機測試很難打滿。
????????所以需要配置 application.yml文件,修改 tomcat 連接:
server:port: 8082tomcat:threads:max: 50 # 允許的最大線程數(shù)accept-count: 50 # 最大排隊等待數(shù)量max-connections: 100 # 允許的最大連接
? ? ? ? 再次查看購物車的查詢接口情況:
????????可以看到查詢商品的 FeignClient 自動變成了一個簇點資源。
? ? ? ? ?4.2 配置線程隔離
? ? ? ? 接下來,點擊查詢商品的 FeignClient 對應的簇點資源后端的流控按鈕:
在彈出的表單中填寫下面內(nèi)容:
在查詢商品的業(yè)務上手動添加阻塞時間從而來模擬阻塞狀態(tài):
????????這里勾選的是并發(fā)線程數(shù)限制,也就是說這個查詢功能最多使用 5 個線程,而不是 5 QPS。
如果查詢商品的接口每秒處理 2 個請求,則 5 個線程的實際 QPS 在 10 左右,而超出的請求自然
會被拒絕。
? ? ? ? 接著測試一下:
利用 Jemeter 測試,每秒發(fā)送 100 個請求:
測試結(jié)果:
????????進入查詢購物車的請求每秒大概在 100,而在查詢商品時卻只剩下每秒 10 左右,符合我們的
預期。
? ? ? ? 當訪問其他正常的接口的時候,響應時間非常短,這就證明線程隔離起到了作用,盡管查詢
購物車這個接口并發(fā)很高,但是它能使用的線程資源被限制了,因此不會影響到其它接口。
? ? ? ? 5.0?Sentinel-Fallback
????????觸發(fā)限流或熔斷后的請求不一定要直接報錯,也可以返回一些默認數(shù)據(jù)或者友好提示,用戶
體驗會更好。
給 FeignClient 編寫失敗后的降級邏輯有兩種方式:
????????方式一:FallbackClass,無法對遠程調(diào)用的異常做處理
????????方式二:FallbackFactory,可以對遠程調(diào)用的異常做處理,一般選擇這種方式。
演示方式二的失敗降級處理:
? ? ? ? 1)在模塊中給 ItemClient 定義降級處理類,實現(xiàn) FallbackFactory:
代碼如下:
@Slf4j public class ItemFallback implements FallbackFactory<ItemClient> {@Overridepublic ItemClient create(Throwable cause) {return new ItemClient() {@Overridepublic List<ItemDTO> queryItemByIds(Collection<Long> ids) {log.error("遠程調(diào)用ItemClient#queryItemByIds方法出現(xiàn)異常,參數(shù):{}", ids, cause);// 查詢購物車允許失敗,查詢失敗,返回空集合return CollUtils.emptyList();}@Overridepublic void deductStock(Collection<OrderDetailDTO> items) {// 庫存扣減業(yè)務需要觸發(fā)事務回滾,查詢失敗,拋出異常throw new BizIllegalException(cause);}};} }
? ? ? ? 2)ItemFallback 注冊為 Bean 對象:
? ? ? ? 3)在模塊中的 ItemClient 接口中聲明使用:
重啟后,再次測試,發(fā)現(xiàn)被限流的請求不再報錯,走了降級邏輯:
? ? ? ? 不會直接報異常錯誤,而是走 Fallback 邏輯:
? ? ? ? 當請求被拒絕之后會來到 Fallback 邏輯,我們寫的 Fallback 邏輯就是打印日志:
? ? ? ? 6.0 Sentinel-服務熔斷
????????Sentinel 中的斷路器不僅可以統(tǒng)計某個接口的慢請求比例,還可以統(tǒng)計異常請求比例。當這
些比例超出閾值時,就會熔斷該接口,即攔截訪問該接口的一切請求,降級處理;當該接口恢復正
常時,再放行對于該接口的請求。
????????斷路器的工作狀態(tài)切換有一個狀態(tài)機來控制:
狀態(tài)機包括三個狀態(tài):
? ? ? ? 1)closed:關閉狀態(tài),斷路器放行所有請求,并開始統(tǒng)計異常比例、慢請求比例。超過閾值
則切換到 open 狀態(tài)。
? ? ? ? 2)open:打開狀態(tài),服務調(diào)用被熔斷,訪問被熔斷服務的請求會被拒絕,快速失敗,直接
走降級邏輯。Open 狀態(tài)持續(xù)一段時間后會進入 half-open 狀態(tài)。
? ? ? ? 3)half-open:半開狀態(tài),放行一次請求,根據(jù)執(zhí)行結(jié)果來判斷接下來的操作。?
????????請求成功:則切換到 closed 狀態(tài)
????????請求失敗:則切換到 open 狀態(tài)
? ? ? ? 6.1 配置熔斷策略
????????可以在控制臺通過點擊簇點后的熔斷按鈕來配置熔斷策略:
? ? ? ? 1)點擊熔斷:
? ? ? ? 2)配置:
這種是按照慢調(diào)用比例來做熔斷,上述配置的含義是:
? ? ? ? 1)RT 超過 200 毫秒的請求調(diào)用就是慢調(diào)用。
? ? ? ? 2)統(tǒng)計最近 1000ms 內(nèi)的最少 5 次請求,如果慢調(diào)用比例不低于 0.5,則觸發(fā)熔斷。
? ? ? ? 3)熔斷持續(xù)時長 20 s 。
配置完成后,再次利用 Jemeter 測試,可以發(fā)現(xiàn):
????????在一開始一段時間是允許訪問的,后來觸發(fā)熔斷后,查詢商品服務的接口通過 QPS 直接為
0,所有請求都被熔斷了。而查詢購物車的本身并沒有受到影響。
此時整個購物車查詢服務的平均 RT 影響不大:
? ? ? ? 希望可以幫助到你!