写点什么

【Spring Cloud 8】熔断与限流 Sentinel,java 常见面试题

用户头像
极客good
关注
发布于: 刚刚

看到这里,你是不是有疑问?为什么一个 context 有且仅有一个 DefaultNode,我们的 resouece 跑哪去了呢,其实,这里的一个 context 有且仅有一个 DefaultNode 是在 NodeSelectorSlot 范围内,NodeSelectorSlot 是 ProcessorSlotChain 中的一环,获取 ProcessorS


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


lotChain 是根据 Resource 维度来的。总结为一句话就是:针对同一个 Resource,多个 context 对应多个 DefaultNode;针对不同 Resource,(不管是否是同一个 context)对应多个不同 DefaultNode。这还没看明白 : ),好吧,我不 bb 了,上图吧:



DefaultNode 结构如下:


public class DefaultNode extends StatisticNode {


private ResourceWrapper id;


/**


  • The list of all child nodes.

  • 子节点集合


*/


private volatile Set<Node> childList = new HashSet<>();


/**


  • Associated cluster node.


*/


private ClusterNode clusterNode;


}


一个 Resouce 只有一个 clusterNode,多个 defaultNode 对应一个 clusterNode,如果 defaultNode.clusterNode 为 null,则在 ClusterBuilderSlot.entry 中会进行初始化。


同一个 Resource,对应同一个 ProcessorSlotChain,这块处理逻辑在 lookProcessChain 方法中,如下:


ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper) {


ProcessorSlotChain chain = chainMap.get(resourceWrapper);


if (chain == null) {


synchronized (LOCK) {


chain = chainMap.get(resourceWrapper);


if (chain == null) {


// Entry size limit.


if (chainMap.size() >= Constants.MAX_SLOT_CHAIN_SIZE) {


return null;


}


chain = SlotChainProvider.newSlotChain();


Map<ResourceWrapper, ProcessorSlotChain> newMap = newHashMap<ResourceWrapper, ProcessorSlotChain>(


chainMap.size() + 1);


newMap.putAll(chainMap);


newMap.put(resourceWrapper, chain);


chainMap = newMap;


}


}


}


return chain;


}

5、StatisticNode

StatisticNode 中保存了资源的实时统计数据(基于滑动时间窗口机制),通过这些统计数据,sentinel 才能进行限流、降级等一系列操作。StatisticNode 属性如下:


public class StatisticNode implements Node {


/**


  • 秒级的滑动时间窗口(时间窗口单位 500ms)


*/


private transient volatile Metric rollingCounterInSecond = newArrayMetric(SampleCountProperty.SAMPLE_COUNT,


IntervalProperty.INTERVAL);


/**


  • 分钟级的滑动时间窗口(时间窗口单位 1s)


*/


private transient Metric rollingCounterInMinute = new ArrayMetric(60, 60 * 1000,false);


/**


  • The counter for thread count.

  • 线程个数用户触发线程数流控


*/


private LongAdder curThreadNum = new LongAdder();


}


public class ArrayMetric implements Metric {


private final LeapArray<MetricBucket> data;


}


public class MetricBucket {


// 保存统计值


private final LongAdder[] counters;


// 最小 rt


private volatile long minRt;


}


其中 MetricBucket.counters 数组大小为 MetricEvent 枚举值的个数,每个枚举对应一个统计项,比如 PASS 表示通过个数,限流可根据通过的个数和设置的限流规则配置 count 大小比较,得出是否触发限流操作,所有枚举值如下:


public enum MetricEvent {


PASS, // Normal pass.


BLOCK, // Normal block.


EXCEPTION,


SUCCESS,


RT,


OCCUPIED_PASS


}

6、Slot

Slot 是 sentinel 中非常重要的概念,sentinel 的工作流程就是围绕着一个个插槽所组成的插槽链来展开的。需要注意的是每个插槽都有自己的职责,他们各司其职完美的配合,通过一定的编排顺序,来达到最终的限流降级。默认的各个插槽之间的顺序是固定的,因为有的插槽需要依赖其他的插槽计算出来的结果才能进行工作。


sentinel 通过 SlotChainBuilder 作为 SPI 接口,使得 Slot Chain 具备了扩展的能力。我们可以通过实现 SlotChainBuilder 接口加入自定义 Slot 并且定义编排各个 slot 之间的排序,从而可以给 sentinel 添加自定义的功能。


那 SlotChain 是在哪创建的呢?是在 CtSph.lookProcessChain() 方法中创建的,并且该方法会根据当前请求的资源先去一个静态的 HashMap 中获取,如果获取不到才会创建,创建后会保存到 HashMap 中。这就意味着,同一个资源会全局共享一个 SlotChain。默认生成 ProcessorSlotChain 为:


// DefaultSlotChainBuilder


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;



六、springcloud 如何使用 sentinel




学习了 sentinel 核心概念之后,感觉整个人都不好了,真的是晦涩难懂,来个 helloworld,轻松一下。

1、pom.xml

<dependency>


<groupId>org.springframework.cloud</groupId>


<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>


</dependency>

2、?controller

@RestController


public class TestController {


@GetMapping(value = "/hello")


@SentinelResource("hello")


public String hello() {


return "Hello Sentinel";


}


}

3、引入 dashboard

直接下载 sentinel-dashboard 的 jar 包。


默认是 8080 端口,在浏览器输入:localhost:8080,默认账号密码:sentinel:sentinel,看到控制台界面为部署成功。


4、application.properties

server.port=8088


spring.application.name=spring-cloud-alibaba-sentinel-demo

sentinel dashboard

spring.cloud.sentinel.transport.dashboard=localhost:8080

5、?启动 spring boot 项目,继续访问 localhost:8080,会看到如下界面

6、?使用 Sentinel 实现接口限流(在控制台)

7、测试

通过上面的配置,实现的是/hello 接口 qps 最大是 2,如果 qps 大于 2,则快速失败,配置完成,点击保存,我们快速刷新浏览器,会发现快速失败



七、总结




本文主要介绍了 Sentinel 的概念、特性、与 Hystrix 的区别、一些核心概念和与 SpringCloud 的简单整合。随着微服务的流行,服务和服务之间的稳定性变得越来越重要。??Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。


每一篇博客都是一种经历,程序猿生涯的痕迹,知识改变命运,命运要由自己掌控,愿你游历半生,归来仍是少年。


欲速则不达,欲达则欲速!

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
【Spring Cloud 8】熔断与限流Sentinel,java常见面试题