Sentinel API
這裏介紹三個重要的API。
- ContextUtil
- Tracer
- SphU
@GetMapping("/test-sentinel-api")
public String testSentinelApi(@RequestParam(required = false) String a) {
//定義一個sentinel受保護的資源,名稱是test-sentinel-api
String resourceName = "test-sentinel-api";
//
ContextUtil.enter(resourceName, "test-wfw");
Entry entry = null;
try {
entry = SphU.entry(resourceName);
//被保護的邏輯
if (StringUtils.isEmpty(a)) {
throw new IllegalArgumentException("a is not null");
}
return a;
} catch (BlockException be) {
//如果受保護的資源被限流或者降級了 就會拋BlockException
log.warn("限流或者降級了", be);
return "限流或者降級了";
} catch (IllegalArgumentException ie) {
//統計 IllegalArgumentException 發生的次數、佔比。。。
Tracer.trace(ie);
return "a is not null";
} finally {
if(entry != null) {
//退出entry
entry.exit();
}
ContextUtil.exit();
}
}
Sentinel 註解
屬性 | 作用 | 是否必須 |
---|---|---|
value | 資源名稱 | 是 |
entryType | entry類型,標記流量的方向,取值IN/OUT,默認是OUT | 否 |
blockHandler | 處理BlockException的函數名稱。函數要求:1.必須是 public 2.返回類型與原方法一致 3.參數類型需要和原方法相匹配,並在最後加 BlockException 類型的參數。4.默認需和原方法在同一個類中。若希望使用其他類的函數,可配置 blockHandlerClass ,並指定blockHandlerClass裏面的方法。 | 否 |
blockHandlerClass | 存放blockHandler的類。對應的處理函數必須static修飾,否則無法解析,其他要求:同blockHandler。 | 否 |
fallback | 用於在拋出異常的時候提供fallback處理邏輯。fallback函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。函數要求:1. 返回類型與原方法一致 2. 參數類型需要和原方法相匹配,Sentinel 1.6開始,也可在方法最後加 Throwable 類型的參數。3.默認需和原方法在同一個類中。若希望使用其他類的函數,可配置 fallbackClass ,並指定fallbackClass裏面的方法。 | 否 |
fallbackClass【1.6】 | 存放fallback的類。對應的處理函數必須static修飾,否則無法解析,其他要求:同fallback。 | 否 |
defaultFallback【1.6】 | 用於通用的 fallback 邏輯。默認fallback函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,以fallback爲準。函數要求:1. 返回類型與原方法一致 2. 方法參數列表爲空,或者有一個 Throwable 類型的參數。3. 默認需要和原方法在同一個類中。若希望使用其他類的函數,可配置 fallbackClass ,並指定 fallbackClass 裏面的方法。 | 否 |
exceptionsToIgnore【1.6】 | 指定排除掉哪些異常。排除的異常不會計入異常統計,也不會進入fallback邏輯,而是原樣拋出。 | 否 |
exceptionsToTrace | 需要trace的異常 | Throwable |
限流處理的方法。
@GetMapping("/test-sentinel-resource")
@SentinelResource(value = "test-sentinel-resource",
blockHandlerClass = TestBlock.class,
blockHandler = "block",
fallbackClass = TestFallBack.class,
fallback = "fallBack"
)
public String testSentinelResource(@RequestParam(required = false) String a) {
if (StringUtils.isEmpty(a)) {
throw new IllegalArgumentException("a is not null");
}
return a;
}
限流處理類。
@Slf4j
@Component
public class TestBlock {
public static String block(String a, BlockException e) {
log.warn("限流 或者 降級 block a:{}", a, e);
return "限流 或者 降級 block";
}
}
降級處理類。
@Slf4j
@Component
public class TestFallBack {
public static String fallBack(String a, Throwable e) {
log.warn("限流 或者 降級 fall a:{}", a, e);
return "限流 或者 降級 fall";
}
}
TIPS
- 1.6.0 之前的版本 fallback 函數只針對降級異常(DegradeException)進行處理,不能針對業務異常進行處理。
- 若 blockHandler 和 fallback 都進行了配置,則被限流降級而拋出 BlockException 時只會進入 blockHandler 處理邏輯。若未配置 blockHandler、fallback 和 defaultFallback,則被限流降級時會將 BlockException 直接拋出。
- 從 1.4.0 版本開始,註解方式定義資源支持自動統計業務異常,無需手動調用 Tracer.trace(ex) 來記錄業務異常。Sentinel 1.4.0 以前的版本需要自行調用 Tracer.trace(ex) 來記錄業務異常。
整合 Feign
-
增加配置
feign: sentinel: enabled: true
-
創建限流處理類
@Slf4j @Component public class UserFallBackFactoryFeign implements FallbackFactory<UserFeign> { @Override public UserFeign create(Throwable throwable) { return id -> { log.warn("限流或降級 id:{}", id, throwable); User user = new User(); user.setName("默認用戶"); return user; }; } } @Slf4j @Component public class UserFallBackFeign implements UserFeign { @Override public User getUserById(Long id) { User user = new User(); user.setName("默認用戶"); return user; } }
-
feign 註解修改
需要注意的是 fallbackFactory 和 fallback 只能存在一個。
@FeignClient(value = "user", //fallbackFactory = UserFallBackFactoryFeign.class, fallback = UserFallBackFeign.class ) public interface UserFeign { @GetMapping("/user/{id}") User getUserById(@PathVariable Long id); }