官方git地址: https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7
使用场景: 项目调用了别人提供的dubbo接口,为避免dubbo服务出现异常,导致dubbo消费者服务异常,所以需要设置熔断降级规则,保护dubbo消费者服务。
1.引入依赖
com.alibaba.csp
1.8.0
com.alibaba.csp
sentinel-annotation-aspectj
1.8.0
com.alibaba.csp
sentinel-apache-dubbo-adapter
1.8.0
2.初始化熔断降级规则--可在启动类中直接调用
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
initFlowRules();
}
}
private static final String KEY = "com.huobi.dgg.uc.facade.LoginFacadeService:checkLogin(java.lang.String)"; // 针对方法级的熔断
private static final String KEY2 = "com.huobi.dgg.uc.facade.LoginFacadeService"; // 针对类级的熔断
private static void initFlowRules() {
List rules = new ArrayList<>();
DegradeRule rule = new DegradeRule( KEY)
// 熔断策略,支持慢调用比例/异常比例/异常数策略
.setGrade(CircuitBreakerStrategy. SLOW_REQUEST_RATIO.getType())
// 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用),Max allowed response time,单位 ms
.setCount(1000 * 3)
//熔断时长,单位为 s, Retry timeout (in second)
.setTimeWindow(5)
// 慢调用比例阈值 Circuit breaker opens when slow request ratio > 60%
.setSlowRatioThreshold(0.8)
// 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断
.setMinRequestAmount(1000)
// 统计时长(单位为 ms) 20000
.setStatIntervalMs(1000 * 60);
rules.add(rule);
DegradeRuleManager. loadRules(rules);
log.info("Degrade rule loaded[{}]", rules);
}
3.使用@SentinelResource注解定义资源,注解方式定义资源支持自动统计业务异常,无需手动调用 Tracer.trace(ex) 来记录业务异常
@Slf4j
@Service
public class UcService {
@DubboReference(group = "${dubbo.group}", version = "${dubbo.version}")
private Service service;
@SentinelResource(value = "checkLogin")
public Result checkLogin(String token) {
return service.checkLogin(token);
}
}
注:完成以上3步,spring boot 即可支持sentinel deubbo熔断降级。
该注解的功能相当于SphU. entry的功能,:
private static AtomicInteger total = new AtomicInteger();
private static AtomicInteger pass = new AtomicInteger();
private static AtomicInteger block = new AtomicInteger();
public UserDO readUserInfo(String token) {
Result result;
Entry entry = null;
try {
// 有可能被编码了,尝试解码
if (token.indexOf('%') != -1) {
token = URLDecoder. decode(token, "utf-8");
}
entry = SphU. entry("com.huobi.dgg.uc.facade.LoginFacadeService:checkLogin(java.lang.String)");
pass.incrementAndGet();
result = loginFacadeService.checkLogin(token);
} catch (BlockException e) {
block.incrementAndGet();
log.info("熔断。。。。");
return null;
} catch (Exception e) {
block.incrementAndGet();
log.error("调用uc dubbo checkLogin异常", e);
return null;
} finally {
total.incrementAndGet();
if (entry != null) {
entry.exit();
}
}
if (result != null && result.isSuccess()) {
return result.getData();
}
if (null == result) {
log.error("调用uc dubbo checkLogin返回null");
} else {
log.info("调用uc dubbo checkLogin返回码[{}], 返回信息[{}]", result.getCode(), result.getMessage());
}
if (env.equalsIgnoreCase("local")) {
UserDO userDO = new UserDO();
userDO.setId(110L);
return userDO;
}
return null;
}