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); }