上一節(jié)整理了Sentinel的限流,限流可以降低微服務的負載,避免因為高并發(fā)而故障,進而傳遞給其他相關服務而引發(fā)服務雪崩。以上僅為避免服務故障,而當某個服務真正故障時,如何處理才能防止服務雪崩? ? Sentinel支持隔離和降級兩種方案
1、線程隔離和熔斷降級
采用線程隔離,即艙壁模式:
- 業(yè)務1:服務A到服務B,限制10線程數(shù)
- 業(yè)務2:服務A到服務C,限制10線程數(shù)
此時,服務C故障,最大損失10個線程,不會長期占用其他線程,如此,服務A到服務B仍可正常訪問,阻止了故障的傳遞。
熔斷降級,即當請求的失敗比例超過閾值時,熔斷器阻斷服務A到服務D的請求,以后服務A到服務D的請求過來就會直接失敗,它沒壓根機會去訪問,也就不會導致資源耗盡,也就不會發(fā)生故障傳遞。
可以看到,不管是線程隔離還是熔斷降級,都是對服務調用方的保護,別因為別的服務故障而拖垮自己。
2、Feign整合Sentinel
SpringCloud中,微服務調用都是通過Feign來實現(xiàn)的,因此做客戶端保護必須整合Feign和Sentinel
- 修改服務調用方的application.yaml文件,開啟Feign的Sentinel功能
feign:
sentinel:
enabled: true # 開啟Feign的Sentinel功能
- 給FeignClient編寫失敗后的降級邏輯(被阻斷了,走另一條路,比如返回msg調用xxService失?。?/li>
方式一:FallbackClass,不能對遠程調用的異常做處理
方式二:FallbackFactory,可以對遠程調用的異常做處理,常選這種
3、FallbackFactory代碼邏輯
這是未處理前,feign處理的接口:
@FeignClient(value = "userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
- 在feing-api項目中定義類,實現(xiàn)FallbackFactory接口,且FallbackFactory的泛型中即為關聯(lián)接口的類型
@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> { //泛型中指定關聯(lián)的接口的類型
@Override
public UserClient create(Throwable throwable) {
// 創(chuàng)建UserClient接口實現(xiàn)類(匿名內部類),實現(xiàn)其中的方法,編寫失敗降級的處理邏輯
return new UserClient() {
@Override
public User findById(Long id) {
// 記錄異常信息
log.error("查詢用戶異常", throwable);
// 根據(jù)業(yè)務需求返回默認的數(shù)據(jù),這里是空用戶
return new User();
}
};
}
}
- 在模塊的配置類DefaultFeignConfiguration中將UserClientFallbackFactory注冊為一個Bean:
public class DefaultFeignConfiguration {
//new個對象返回
@Bean
public UserClientFallbackFactory userClientFallbackFactory(){
return new UserClientFallbackFactory();
}
}
- 在feing-api項目中的UserClient接口中用fallbackFactory屬性,使用UserClientFallbackFactory
@FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
- 重啟服務,在Sentinel簇點鏈路中可以看到被遠程調用的服務
到此,F(xiàn)eign整合Sentinel成功。也可再看下降級處理的效果(停掉被調用服務):
4、線程隔離
實現(xiàn)線程隔離有兩種方式:
- 線程池隔離
- 信號量隔離(Sentinel默認采用)
基于信號量即這個資源請求能用的線程就10個,有個計數(shù)器,用一個少一個,請求完后還回去,用完后面的請求就沒得用了,以達到艙壁隔離的效果。
兩種方式的優(yōu)缺點:
- 基于計數(shù)器模式,簡單,開銷小
- 基于線程池模式,有額外開銷,但隔離控制更強
Sentinel中的配置示例如下:
- QPS:就是每秒的請求數(shù)
- 線程數(shù):是該資源能使用用的tomcat線程數(shù)的最大值。也就是通過限制線程數(shù)量,實現(xiàn)艙壁模式
需求:給 UserClient的查詢用戶接口設置流控規(guī)則,線程數(shù)不能超過 2
- Sentinel中添加流控規(guī)則,閾值類型選擇線程數(shù)
- 啟動Jmeter,對/order/101發(fā)起測試
- 查看結果數(shù),10個請求,8個返回結果user為null且控制臺輸出報錯日志(請求不會失敗,因為上面已經做了降級的邏輯處理)
5、Sentinel熔斷的實現(xiàn)原理
由斷路器統(tǒng)計服務調用的異常比例、慢請求比例,如果超出閾值則會熔斷該服務。即攔截訪問該服務的一切請求;而當服務恢復時,斷路器才會放行訪問該服務的請求。實現(xiàn)思路如下:
- 斷路器處于closed時,一切請求都不被攔截,且會被統(tǒng)計異常和慢的比例
- 當比例達到失敗閾值,斷路器open,所有請求一過來就快速失敗
- 當熔斷時間結束,切換好半開放狀態(tài),即Half-Open
- Half-Open狀態(tài)會嘗試放行一些請求,如果依舊失敗,則回到Open狀態(tài)繼續(xù)攔截,如果成功,則回到Closed狀態(tài)
6、熔斷策略–慢調用
達到某個閾值時,觸發(fā)熔斷,這個就是斷路器的熔斷策略,分為這三種:慢調用、異常比例、異常數(shù)
慢調用:業(yè)務的響應時長(RT)大于指定時長的請求認定為慢調用請求。在指定時間內,如果請求數(shù)量超過設定的最小數(shù)量,慢調用比例大于設定的閾值,則觸發(fā)熔斷。
關于慢調用,即正常蹲坑6分鐘,你蹲一小時,半天不釋放資源,自然會影響到其他請求。
以上這個Sentinel配置,即:
- RT超過500ms的調用是慢調用
- 統(tǒng)計最近10000ms內的請求
- 如果請求量超過10次,并且慢調用比例不低于0.5,則觸發(fā)熔斷
- 熔斷時長為5秒,然后進入half-open狀態(tài),放行一次請求做測試
接下來完成一個實際例子:
需求:
給 UserClient的查詢用戶接口設置降級規(guī)則,慢調用的RT閾值為50ms,統(tǒng)計時間為1秒,最小請求數(shù)量為5,失敗閾值比例為0.4,熔斷時長為5
為了觸發(fā)慢調用規(guī)則,這里修改UserService中的業(yè)務,使用休眠來模擬慢調用:
開始演示:
- 配置Sentinel降級規(guī)則
- 狂刷/order/101接口(或者Ctrl+R),/order/101調用的user id就是1,即可觸發(fā)熔斷
- 此時訪問其他用戶,也返回空,因為阻斷器open,直接擋回去了
- 估摸著5s過去了,阻斷器進入到了Half-Open,再重新請求,可以看到正常返回了,當然此時熔斷器變?yōu)镃losed狀態(tài)
7、熔斷策略–異常比例、異常數(shù)
一定時間內的請求,異常請求所占的比例達到設定的比例閾值,或者異常請求的數(shù)量達到了設定的數(shù)量閾值,即熔斷。
此配置即統(tǒng)計最近1000ms內的請求,如果請求量超過10次,并且異常比例不低于0.4,則觸發(fā)熔斷,熔斷時長為5秒。然后進入half-open狀態(tài),放行一次請求做測試。
此配置即統(tǒng)計最近1000ms內的請求,如果請求量超過10次,并且異常數(shù)不低于2個,就觸發(fā)熔斷,熔斷時長為5秒。然后進入half-open狀態(tài),放行一次請求做測試。
需求:
給 UserClient的查詢用戶接口設置降級規(guī)則,統(tǒng)計時間為1秒,最小請求數(shù)量為5,失敗閾值比例為0.4,熔斷時長為5s
這里手動拋異常模擬異常的發(fā)生:
- 配置降級規(guī)則
- 刷/order/102,查uid為2的用戶,達到異常比例來觸發(fā)熔斷
- 然后再訪問/order/103,此時103立即失?。ū蛔钄嗔耍院臅r極小,這里只有7ms)
- 等過了阻斷器open的時間,再訪問就正常了
熔斷策略小結:文章來源:http://www.zghlxwxcb.cn/news/detail-583310.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-583310.html
到了這里,關于Sentinel的線程隔離和熔斷降級的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!