开源项目中的设计模式(一) - Alibaba Sentinel与责任链模式

责任链模式

责任链模式是一种行为型设计模式,他通过将一系列的操作行为串联成一个链路构造出一个链式的结构,每一次调用链路的时候,链路上的每一个行为都可能会对此次调用进行一定的处理。

责任链模式可以用于权限控制,OA流程等等,当然在Java Web中的Filter也使用到了这种设计模式。

Alibaba Sentinel

回到我们的正题,接下来我将讲述开源项目Alibaba Sentinel是如何在项目中应用责任链模式的。

Alibaba Sentinel是一个开源的高可用防护组件,实现了限流熔断等能力。

对于限流熔断的通用场景来说,我们会涉及到的麻烦事在于用户可能会配置非常多的规则,并且每种规则可能有不同的处理逻辑。在这种场合下显然使用责任链模式是非常合适的。

那么我们来看下Sentinel是如何来实现责任链的。

实战

Sentinel定义了一个接口ProcessorSlot,这个接口就是责任链模式的实现核心。

在这个接口中定义了四个方法:

  1. entry 进入Slot
  2. fireEntry entry执行完成后调用
  3. exit 离开Slot
  4. fireExit exit执行完成后调用

ProcessorSlot为基础,Sentinel定义了抽象实现类AbstractLinkedProcessorSlot,之后包括FlowSlotDegradeSlot等等实现都继承了这个抽象类来实现,这些Slot就是整个责任链的链路了。

Sentinel通过SlotChainBuilder来对责任链的整个链路进行初始化。在默认实现中各个Slot使用Spi的形式进行定义和管理,并且在此处使用ServiceLoader来进行装载。也就是在此时决定了整个链路的执行顺序和优先级。后续的流量进入之后就会按照预定的顺序执行每个Slot的方法。

Sentinel定义了SphUSphO等类来实现流量的入口管控,之后流量就会进入到整个链路中执行整个责任链。

java 复制代码
Entry e = new CtEntry(resourceWrapper, chain, context, count, argMap);
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);
}

责任链模式在Sentinel中的作用

回过头来看整个责任链模式在这个场合中的使用,我们不难发现其优势,在开源项目不断迭代新增功能的情况下,责任链模式对于后续的能力拓展非常有利。如果将来需要新增一种流量的校验模式,我们只需要继承AbstractLinkedProcessorSlot申明一个新的Slot,并且设定好这个Slot的执行顺序,我们无需修改任何之前的代码。

在这种设计下完美符合开闭原则,并且从代码设计上来说也更加利于整理的流程控制。比如在Sentinel中做数据统计也同样是新增了Slot来实现的,从这种角度上来说确实是十分便利。

总结

在这个系列中我不会重复向大家介绍每个设计模式的形态和使用方式,我只会单纯向大家展示开源项目中是如何使用到了这些设计方式,这么做的优势是什么。

相关推荐
Rust研习社11 分钟前
Once、OnceCell、OnceLock:Rust 一次性初始化终极指南
后端·rust·编程语言
Rust研习社13 分钟前
从入门到实践:Rust 异步编程完全指南
开发语言·后端·rust
GreenTea17 分钟前
DeepSeek-V4 技术报告深度分析:基础研究创新全景
前端·人工智能·后端
yaoxin52112317 分钟前
389. Java IO API - 获取文件名
java·开发语言·python
用户83562907805129 分钟前
使用 Python 自动管理 PowerPoint 幻灯片分节的方法
后端·python
Wang15301 小时前
Java排序
java
逸风尊者1 小时前
XGBoost模型工程使用
java·后端·算法
一嘴一个橘子1 小时前
MP 自定义业务方法 (二)
java
低客的黑调1 小时前
MyBatis-Plus-从 CRUD 到高级特性
java·servlet·tomcat
ekuoleung1 小时前
量化平台中的 DSL 设计与实现:从规则树到可执行策略
前端·后端