基于sentinel 1.8.6
 
 从sentinel-dashboard来看,sentinel主要提供了流控,熔断,热点,系统规则,授权规则等。
针对http请求的数据监控以及规则限制的适配,可以参考sentinel-spring-webmvc-adapter以及sentinel-web-servlet-adapter
 具体的实现类
com.alibaba.csp.sentinel.adapter.servlet.CommonFilter
com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor
一个是基于spring的HandlerInterceptor,一个是基于servlet的Filter。
以com.alibaba.csp.sentinel.adapter.servlet.CommonFilter为例
 
 init,doFilter,destory这三个方法分别对应初始化,逻辑处理,执行完处理的逻辑,重点放在doFilter()方法。
@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest sRequest = (HttpServletRequest) request;
        Entry urlEntry = null;
        try {
            String target = FilterUtil.filterTarget(sRequest);
            // Clean and unify the URL.
            // For REST APIs, you have to clean the URL (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or
            // the amount of context and resources will exceed the threshold.
            UrlCleaner urlCleaner = WebCallbackManager.getUrlCleaner();
            if (urlCleaner != null) {
                target = urlCleaner.clean(target);
            }
            // If you intend to exclude some URLs, you can convert the URLs to the empty string ""
            // in the UrlCleaner implementation.
            if (!StringUtil.isEmpty(target)) {
            	//解析来源
                String origin = parseOrigin(sRequest);
                String contextName = webContextUnify ? WebServletConfig.WEB_SERVLET_CONTEXT_NAME : target;
                //设置上下文
                ContextUtil.enter(contextName, origin);
				//执行sentinel一系列规则,各种校验。
                if (httpMethodSpecify) {
                    // Add HTTP method prefix if necessary.
                    String pathWithHttpMethod = sRequest.getMethod().toUpperCase() + COLON + target;
                    urlEntry = SphU.entry(pathWithHttpMethod, ResourceTypeConstants.COMMON_WEB, EntryType.IN);
                } else {
                    urlEntry = SphU.entry(target, ResourceTypeConstants.COMMON_WEB, EntryType.IN);
                }
            }
            //真正的执行请求
            chain.doFilter(request, response);
        } catch (BlockException e) {
            HttpServletResponse sResponse = (HttpServletResponse) response;
            // Return the block page, or redirect to another URL.
            WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, e);
        } catch (IOException | ServletException | RuntimeException e2) {
            Tracer.traceEntry(e2, urlEntry);
            throw e2;
        } finally {
            if (urlEntry != null) {
                urlEntry.exit();
            }
            ContextUtil.exit();
        }
    }
主要看下在执行真正的chain.doFilter()执行前,sentinel都做了些什么?
com.alibaba.csp.sentinel.SphU#entry(java.lang.String, int, com.alibaba.csp.sentinel.EntryType)
com.alibaba.csp.sentinel.CtSph#entryWithPriority(com.alibaba.csp.sentinel.slotchain.ResourceWrapper, int, boolean, java.lang.Object...)
private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args)
        throws BlockException {
        Context context = ContextUtil.getContext();
        if (context instanceof NullContext) {
            // The {@link NullContext} indicates that the amount of context has exceeded the threshold,
            // so here init the entry only. No rule checking will be done.
            return new CtEntry(resourceWrapper, null, context);
        }
        if (context == null) {
            // Using default context.
            context = InternalContextUtil.internalEnter(Constants.CONTEXT_DEFAULT_NAME);
        }
        // Global switch is close, no rule checking will do.
        if (!Constants.ON) {
            return new CtEntry(resourceWrapper, null, context);
        }
		//初始化流控规则的chain链
        ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);
        /*
         * Means amount of resources (slot chain) exceeds {@link Constants.MAX_SLOT_CHAIN_SIZE},
         * so no rule checking will be done.
         */
        if (chain == null) {
            return new CtEntry(resourceWrapper, null, context);
        }
        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);
        }
        return e;
    }
 ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper); 这个方法会初始化默认的规则校验链,说白了就是流控,熔断...这些规则,我该怎么一个一个的进行校验。
com.alibaba.csp.sentinel.slotchain.SlotChainProvider#newSlotChain
com.alibaba.csp.sentinel.spi.SpiLoader#loadFirstInstanceOrDefault

sentinel基于SPI的方式实现了一个默认的处理链,接口为com.alibaba.csp.sentinel.slotchain.SlotChainBuilder的实现
 
 
 
 处理链的每一个slot都是实现ProcessorSolt。
 
 
 
 以熔断为例,她是一个扩展的spi接口,并且设置了优先级,所以初始化后的规则校验链如下图所示
 
 到目前为止,大致清楚了,我们在sentinel设置了一些类型的规则,规则校验的顺序是什么?怎么实现,如何加载的应该已经很清晰了。
再回到com.alibaba.csp.sentinel.CtSph#entryWithPriority(com.alibaba.csp.sentinel.slotchain.ResourceWrapper, int, boolean, java.lang.Object...)这个方法中,执行的具体方法为com.alibaba.csp.sentinel.slotchain.ProcessorSlot#entry
以流控校验为例
 
 执行flowSlot的entry方法时,会从上下文中获取该资源的统计信息。并与当前类型的规则进行比较,并更新进统计信息。
 统计信息存储在StatisticNode里。包括当前资源名,执行了通过多少次,拒绝多少次等信息。
com.alibaba.csp.sentinel.node.StatisticNode
以上大致就是http请求,sentinel处理的流程,对于dubbo请求,参考类
com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter
com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboConsumerFilter
dubbo支持应用本身作为消费者以及生产者的调用信息的统计。








![[论文解析] Diffusion Guided Domain Adaptation of Image Generators](https://img-blog.csdnimg.cn/5940fad334b04157837dbfd32870970a.png)







![[附源码]Node.js计算机毕业设计高校创新学分申报管理系统Express](https://img-blog.csdnimg.cn/b1e9540c62794d8fb5f689560c82ad81.png)


