零、系列
歡迎來嫖從零開始SpringCloud Alibaba電商系列:
- 從零開始SpringCloud Alibaba電商系統(一)——Alibaba與Nacos服務註冊與發現
- 從零開始SpringCloud Alibaba電商系統(二)——Nacos配置中心
- 從零開始SpringCloud Alibaba電商系統(三)——Sentinel流量防衛兵介紹、流量控制demo
- 從零開始SpringCloud Alibaba電商系統(四)——Sentinel的fallback和blockHandler
- 從零開始SpringCloud Alibaba電商系統(五)——Feign Demo,Sentinel+Feign實現多節點間熔斷/服務降級
- 從零開始SpringCloud Alibaba電商系統(六)——Sentinel規則持久化到Nacos配置中心
一、什麼是fallback和blockHandler?
前文(從零開始SpringCloud Alibaba電商系統(三)——Sentinel流量防衛兵介紹、流量控制demo)我們介紹了Sentinel的限流、服務降級功能,但是隻是限制肯定是不夠了,我們還要保證調用這些被限制服務的調用者,讓他們拿到一個合理的結果,而不是扔回去一個異常就完事了。
Sentinel提供了這樣的功能,讓我們可以另外定義一個方法來代替被限制或異常服務返回數據,這就是fallback和blockHandler。
fallback:失敗調用,若本接口出現未知異常,則調用fallback指定的接口。
blockHandler:sentinel定義的失敗調用或限制調用,若本次訪問被限流或服務降級,則調用blockHandler指定的接口。
幹說不易理解,讓我們用demo來說話。
二、fallback
- 接着我們之前的demo來加代碼,編寫TestController,爲test方法的@SentinelResource註解增加fallback屬性。
這裏直接讓test接口拋出異常,測試f是否會用fallback指定的接口來替代。
package com.lele.mall.controller;/*
* com.lele.mall.controller
* @author: lele
*/
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
// fallbackClass爲異常是調用的方法所屬的類,fallback爲fallbackClass類中的方法。
@SentinelResource(value="test",fallback = "testFallback",fallbackClass = TestController.class)
@GetMapping(value = "/test")
public String test(@RequestParam String name){
throw new RuntimeException("asdasd");
//return name;
}
@GetMapping(value = "/testFallback")
public String testFallback(@RequestParam String name){
return "testFallback"+name;
}
}
- 訪問test接口:localhost:8081/test?name=123,發現返回結果不是500而是testFallback函數的返回值,測試成功!
三、blockHandler
測試超出流量限制的部分是否會進入到blockHandler的方法。
- 爲test方法的@SentinelResource註解增加blockHandler屬性,並增加blockHandler指向的方法。
package com.lele.mall.controller;/*
* com.lele.mall.controller
* @author: lele
*/
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@SentinelResource(value="test",fallback = "testFallback",fallbackClass = TestController.class,blockHandler = "testBlockHandler",blockHandlerClass = TestController.class)
@GetMapping(value = "/test")
public String test(@RequestParam String name){
throw new RuntimeException("asdasd");
//return name;
}
@GetMapping(value = "/testFallback")
public String testFallback(@RequestParam String name){
return "testFallback"+name;
}
@GetMapping(value = "/testBlockHandler")
public String testBlockHandler(@RequestParam String name,BlockException ex){
return "testBlockHandler"+name;
}
}
- 如前文一樣,我們在sentinel dashboard設置流量控制,QPS閾值爲1。
發現快速訪問兩次,第一次調用到了fallback(因爲我們的test方法是直接拋出異常,所以第一次會用fallback替代),第二次調用到了blockHandler。
測試成功!證明流量超限後會調用到blockHandler。
四、服務降級(應用場景)
如上面的測試結果,當超出流量限制或服務降級規則後,我們的服務請求會被降級爲blockHandler方法,這就是服務降級。
再來舉一個應用場景更形象的理解服務降級這四個字:
電商系統在查詢商品是有許多排序規則的,我們一般請求都會請求到帶有排序規則的商品列表,但是如果某一時刻流量猛增,該接口響應時間過慢,就可以進行服務降級,調用降級接口,返回不排序的商品列表。
服務降級可以是連續的,即降級一次慢,那就再降。
一般在微服務系統中,各個微服務之間互相調用,有時候可能網絡故障不通,這時候就可以通過Sentinel+Feign來實現較好的熔斷機制,這部分我們下次再聊。
五、demo地址
上述代碼我已上傳至github/gitee,對[從零開始SpringCloud Alibaba電商系統系列]感興趣的朋友可以點個star。
https://github.com/flyChineseBoy/lel-mall/tree/master/mall04