开源框架中的责任链模式实践( 五 )

  • 整个责任链上处理器的执行通过Invoker对象的驱动 , 而非责任链对象的驱动 。
  • 3.4 Sentinel3.4.1 Sentinel Slot介绍
    开源框架中的责任链模式实践

    文章插图
    • Sentinel是面向分布式服务架构的流量治理组件,以流量为切入点提供熔断限流的功能保证系统的稳定性 。
    • Sentinel 里面以Entry作为限流的资源对象,每个Entry创建的同时会关联一系列功能插槽(slot chain) 。
    • Sentinel提供了通用的原生Slot处理不同的逻辑 , 同时支持自定义Slot来定制功能 。
    3.4.2 处理器介绍
    public interface ProcessorSlot<T> {void entry(Context context, ResourceWrapper resourceWrapper, T param, int count, boolean prioritized,Object... args) throws Throwable;void fireEntry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized,Object... args) throws Throwable;void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args);void fireExit(Context context, ResourceWrapper resourceWrapper, int count, Object... args);}public abstract class AbstractLinkedProcessorSlot<T> implements ProcessorSlot<T> {private AbstractLinkedProcessorSlot<?> next = null;@Overridepublic void fireEntry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)throws Throwable {// 触发下一个处理器对象的处理if (next != null) {next.transformEntry(context, resourceWrapper, obj, count, prioritized, args);}}void transformEntry(Context context, ResourceWrapper resourceWrapper, Object o, int count, boolean prioritized, Object... args)throws Throwable {T t = (T)o;// 执行具体处理器的逻辑,由具体的处理器自行实现entry(context, resourceWrapper, t, count, prioritized, args);}public void setNext(AbstractLinkedProcessorSlot<?> next) {// 绑定下一个处理器的逻辑this.next = next;}} public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);@Overridepublic void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)throws Throwable {// 1、处理器处理本身的逻辑DefaultNode node = map.get(context.getName());context.setCurNode(node);// 2、处理器驱动触发下一个处理器fireEntry(context, resourceWrapper, node, count, prioritized, args);}}说明:
    • Sentinel中的Slot需要实现
      com.alibaba.csp.sentinel.slotchain.ProcessorSlot的通用接口 。
    • 自定义Slot一般继承抽象类AbstractLinkedProcessorSlot且只要改写entry/exit方法实现自定义逻辑 。
    • Slot通过next变量保存下一个处理器Slot对象 。
    • 在自定义实现的entry方法中需要通过fireEntry触发下一个处理器的执行,在exit方法中通过fireExit触发下一个处理器的执行 。
    3.4.3 责任链构建
    public class DefaultSlotChainBuilder implements SlotChainBuilder {@Overridepublic ProcessorSlotChain build() {// 责任链的头部对象ProcessorSlotChainProcessorSlotChain chain = new DefaultProcessorSlotChain();// sortedSlotList获取所有的处理器对象List<ProcessorSlot> sortedSlotList = SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted();for (ProcessorSlot slot : sortedSlotList) {if (!(slot instanceof AbstractLinkedProcessorSlot)) {continue;}// 通过尾添法将职责slot添加到DefaultProcessorSlotChain当中chain.addLast((AbstractLinkedProcessorSlot<?>) slot);}return chain;}}public class DefaultProcessorSlotChain extends ProcessorSlotChain {// 创建DefaultProcessorSlotChain的头尾节点first和endAbstractLinkedProcessorSlot<?> first = new AbstractLinkedProcessorSlot<Object>() {@Overridepublic void entry(Context context, ResourceWrapper resourceWrapper, Object t, int count, boolean prioritized, Object... args)throws Throwable {super.fireEntry(context, resourceWrapper, t, count, prioritized, args);}@Overridepublic void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {super.fireExit(context, resourceWrapper, count, args);}};AbstractLinkedProcessorSlot<?> end = first;@Overridepublic void addLast(AbstractLinkedProcessorSlot<?> protocolProcessor) {end.setNext(protocolProcessor);end = protocolProcessor;}}说明: