编程语言
首页 > 编程语言> > 深入剖析阿里sentinel源码,看这篇就够了

深入剖析阿里sentinel源码,看这篇就够了

作者:互联网

1.1. 引言

1.2. 源码

1.2.1. 流控降级监控等的构建

深入剖析阿里sentinel源码,看这篇就够了

 

Entry e = new CtEntry(resourceWrapper, chain, context);
 try {
 chain.entry(context, resourceWrapper, null, count, prioritized, args);
 } catch (BlockException e1) {
 e.exit(count, args);
 throw e1;
 } catch (Throwable e1) {
 // This should not happen, unless there are errors existing in Sentinel internal.
 RecordLog.info("Sentinel unexpected exception", e1);
 }

1.2.2. 修改控制台规则是如何通知客户端的?

// Find the matching command handler.
 CommandHandler<?> commandHandler = SimpleHttpCommandCenter.getHandler(commandName);
 if (commandHandler != null) {
 CommandResponse<?> response = commandHandler.handle(request);
 handleResponse(response, printWriter, outputStream);
 } else {
 // No matching command handler.
 badRequest(printWriter, "Unknown command `" + commandName + '`');
 }

通过命令模式,commandName为setRules时,更新规则

1.2.3. 既然它建立连接用的socket,为什么不用netty呢?

1.2.4. 流量规则如何检查?

 private static boolean passLocalCheck(FlowRule rule, Context context, DefaultNode node, int acquireCount,
 boolean prioritized) {
 Node selectedNode = selectNodeByRequesterAndStrategy(rule, context, node);
 if (selectedNode == null) {
 return true;
 }
 return rule.getRater().canPass(selectedNode, acquireCount, prioritized);
 }

1.2.5. 熔断降级如何判断?

 public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count)
 throws BlockException {
 Set<DegradeRule> rules = degradeRules.get(resource.getName());
 if (rules == null) {
 return;
 }
 for (DegradeRule rule : rules) {
 if (!rule.passCheck(context, node, count)) {
 throw new DegradeException(rule.getLimitApp(), rule);
 }
 }
 }

1.2.6. 默认的链条构建在哪?

public class DefaultSlotChainBuilder implements SlotChainBuilder {
 @Override
 public ProcessorSlotChain build() {
 ProcessorSlotChain chain = new DefaultProcessorSlotChain();
 chain.addLast(new NodeSelectorSlot());
 chain.addLast(new ClusterBuilderSlot());
 chain.addLast(new LogSlot());
 chain.addLast(new StatisticSlot());
 chain.addLast(new SystemSlot());
 chain.addLast(new AuthoritySlot());
 chain.addLast(new FlowSlot());
 chain.addLast(new DegradeSlot());
 return chain;
 }
}

1.2.7. 既然已经知道了它是如何构建链式的处理节点的,我们是否何可自己重新构建?

private static void resolveSlotChainBuilder() {
 List<SlotChainBuilder> list = new ArrayList<SlotChainBuilder>();
 boolean hasOther = false;
 for (SlotChainBuilder builder : LOADER) {
 if (builder.getClass() != DefaultSlotChainBuilder.class) {
 hasOther = true;
 list.add(builder);
 }
 }
 if (hasOther) {
 builder = list.get(0);
 } else {
 // No custom builder, using default.
 builder = new DefaultSlotChainBuilder();
 }
 RecordLog.info("[SlotChainProvider] Global slot chain builder resolved: "
 + builder.getClass().getCanonicalName());
 }
private static final ServiceLoader<SlotChainBuilder> LOADER = ServiceLoader.load(SlotChainBuilder.class);

1.2.8. 如何实现SlotChainBuilder接口呢?

/**
 * @author laoliangliang
 * @date 2019/7/25 14:13
 */
public class MySlotChainBuilder implements SlotChainBuilder {
 @Override
 public ProcessorSlotChain build() {
 ProcessorSlotChain chain = new DefaultProcessorSlotChain();
 chain.addLast(new NodeSelectorSlot());
 chain.addLast(new ClusterBuilderSlot());
 chain.addLast(new LogSlot());
 chain.addLast(new StatisticSlot());
 chain.addLast(new SystemSlot());
 chain.addLast(new AuthoritySlot());
 chain.addLast(new FlowSlot());
 chain.addLast(new DegradeSlot());
 //自定义的
 chain.addLast(new CarerSlot());
 return chain;
 }
}
/**
 * @author laoliangliang
 * @date 2019/7/25 14:15
 */
@Slf4j
public class CarerSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
 @Override
 public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,
 boolean prioritized, Object... args) throws Throwable {
 log.info(JSON.toJSONString(resourceWrapper));
 fireEntry(context, resourceWrapper, node, count, prioritized, args);
 }
 @Override
 public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
 fireExit(context, resourceWrapper, count, args);
 }
}

深入剖析阿里sentinel源码,看这篇就够了

 

1.2.9. 该命令模式最初的初始化阶段在哪?

public class Env {
 public static final Sph sph = new CtSph();
 static {
 // If init fails, the process will exit.
 InitExecutor.doInit();
 }
}
 public static Entry entry(String name) throws BlockException {
 return Env.sph.entry(name, EntryType.OUT, 1, OBJECTS0);
 }

1.2.10. 注解是如何实现熔断降级的?

 @Bean
 public SentinelResourceAspect sentinelResourceAspect() {
 pushlish();
 return new SentinelResourceAspect();
 }
 @Pointcut("@annotation(com.alibaba.csp.sentinel.annotation.SentinelResource)")
 public void sentinelResourceAnnotationPointcut() {
 }

对@SentinelResource注解进行了处理

1.2.11. 什么是直接失败?

深入剖析阿里sentinel源码,看这篇就够了

 

1.2.12. 什么是排队等待?

深入剖析阿里sentinel源码,看这篇就够了

 

深入剖析阿里sentinel源码,看这篇就够了

 

1.2.13. 什么是慢启动模式?

 @Override
 public boolean canPass(Node node, int acquireCount, boolean prioritized) {
 long passQps = (long) node.passQps();
 long previousQps = (long) node.previousPassQps();
 syncToken(previousQps);
 // 开始计算它的斜率
 // 如果进入了警戒线,开始调整他的qps
 long restToken = storedTokens.get();
 if (restToken >= warningToken) {
 long aboveToken = restToken - warningToken;
 // 消耗的速度要比warning快,但是要比慢
 // current interval = restToken*slope+1/count
 double warningQps = Math.nextUp(1.0 / (aboveToken * slope + 1.0 / count));
 if (passQps + acquireCount <= warningQps) {
 return true;
 }
 } else {
 if (passQps + acquireCount <= count) {
 return true;
 }
 }
 return false;
 }

深入剖析阿里sentinel源码,看这篇就够了

 

深入剖析阿里sentinel源码,看这篇就够了

 

1.2.14. 模式总结

深入剖析阿里sentinel源码,看这篇就够了

 

深入剖析阿里sentinel源码,看这篇就够了

 

深入剖析阿里sentinel源码,看这篇就够了

 

深入剖析阿里sentinel源码,看这篇就够了

 

1.2.15. 提醒

标签:chain,addLast,这篇,源码,1.2,sentinel,new,public
来源: https://blog.csdn.net/Java666999/article/details/98996845