开源项目中的设计模式(一) - 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来实现的,从这种角度上来说确实是十分便利。

总结

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

相关推荐
前端 贾公子10 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_9622035110 小时前
Java进阶07集合(续)
java·开发语言
尘中远10 小时前
7大开源Agent源码对比解读——性能设计
ai·开源·agent·codex·deepseek·harness
郑州光合科技余经理11 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
IT_陈寒11 小时前
Vue的嵌套组件竟然吃掉了我的事件?
前端·人工智能·后端
roman_日积跬步-终至千里11 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
落魄大学生之流水线上谋生计11 小时前
LangGraph 基本用法指南
java·windows·python·langchain
2601_9621284111 小时前
SpringBoot篇(缓存层)
java·spring boot·缓存
Dovis(誓平步青云)12 小时前
折叠屏悬停看视频,上半屏和下半屏应该各做什么
android·java·服务器·开发语言·安全·音视频
大辉狼_音频架构12 小时前
进阶:从源码编译 SOF 固件与 topology
后端