当前位置: 首页 > wzjs >正文

企业网站建设专业的最优惠的手机网站建设

企业网站建设专业的,最优惠的手机网站建设,wordpress自动视频播放,oa报表网站开发目录 滑动窗口算法 Sentinel 数据模型 示例 大致流程 ​​​​​​​entry ​​​​​​​entryWithPriority ​​​​​​​FlowSlot.entry ​​​​​​​checkFlow ​​​​​​​canPass ​​​​​​​avgUsedTokens ​​​​​​​passQps ​​​​​​​pa…

目录

滑动窗口算法

Sentinel

数据模型

示例

大致流程

​​​​​​​entry

​​​​​​​entryWithPriority

​​​​​​​FlowSlot.entry

​​​​​​​checkFlow

​​​​​​​canPass

​​​​​​​avgUsedTokens

​​​​​​​passQps

​​​​​​​pass

​​​​​​​currentWindow

calculateTimeIdx

​​​​​​​calculateWindowStart

​​​​​​​values


滑动窗口算法

       滑动窗口算法是将时间周期分为n个小周期,分别记录每个小周期内的访问次数,并且根据时间滑动删除过期的小周期。

       如下图,假设时间周期为1min,将1min再分割成2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内访问数量为75,第二个时间周期内访问数量为100,超过100的数量被限流掉了。


       由此可见,当滑动窗口格子划分得越多,那么滑动窗口的滚动就越平滑,限流的统计就越精确。可以很好的解决固定窗口的流动问题。

Sentinel

       滑动窗口算法也是Sentinel的默认算法。

​​​​​​​数据模型

英文名称

中文名称

备注

array

窗口数组

windowLengthInMs

单个窗口时间长度

sampleCount

总窗口数量

intervalInMs

时间窗口总长度

sampleCount * windowLengthInMs

示例

public static void main(String[] args) throws Exception {
    //加载流控规则
    initFlowRules();
    for (int i = 0; i < 5; i++) {
        Thread.sleep(200);
        Entry entry = null;
        try {
            entry = SphU.entry("sayHello");
            //被保护的逻辑
            log.info("访问sayHello资源");
        } catch (Exception ex) {
            log.info("被流量控制了,可以进行降级处理");
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }
}
private static void initFlowRules() {
    List<FlowRule> rules = new ArrayList<>();
    // 创建一个流控规则
    FlowRule rule = new FlowRule();
    // 对sayHello这个资源限流
    rule.setResource("sayHello");
    // 基于qps限流
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // qps最大为2,超过2就要被限流
    rule.setCount(2);
    rules.add(rule);
    // 设置规则
    FlowRuleManager.loadRules(rules);
}

大致流程

    点击示例里的entry()方法,如下所示:

​​​​​​​entry

public Entry entry(ResourceWrapper resourceWrapper, int count, Object... args) throws BlockException {
    return entryWithPriority(resourceWrapper, count, false, args);
}

        点击entryWithPriority()方法,如下所示:

​​​​​​​entryWithPriority

private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args) throws BlockException {
    .. ...
    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;
}

       点击chain.entry()方法,因为我们这次探究的是限流算法,所以选择FlowSlot类,如下所示:

​​​​​​​FlowSlot.entry

public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args) throws Throwable {
    checkFlow(resourceWrapper, context, node, count, prioritized);
    fireEntry(context, resourceWrapper, node, count, prioritized, args);
}

        点击checkFlow()方法,如下所示:

​​​​​​​checkFlow

public void checkFlow(Function<String, Collection<FlowRule>> ruleProvider, ResourceWrapper resource, Context context, DefaultNode node, int count, boolean prioritized) throws BlockException {

        if (ruleProvider == null || resource == null) {

            return;

        }

        Collection<FlowRule> rules = ruleProvider.apply(resource.getName());

        if (rules != null) {

            for (FlowRule rule : rules) {

                if (!canPassCheck(rule, context, node, count, prioritized)) {

                    throw new FlowException(rule.getLimitApp(), rule);

                }

            }

        }

}

​​​​​​​canPass

public boolean canPass(Node node, int acquireCount, boolean prioritized) {
    int curCount = avgUsedTokens(node);
    if (curCount + acquireCount > count) {
        ... ...
        return false;
    }
    return true;
}

       在这里,获取已经使用的token数量,加上待申请的数量,如果超过流控规则里设置的最大值,则返回false。

       点击avgUsedTokens()方法,如下所示:

​​​​​​​avgUsedTokens

private int avgUsedTokens(Node node) {

        if (node == null) {

            return DEFAULT_AVG_USED_TOKENS;

        }

        return grade == RuleConstant.FLOW_GRADE_THREAD ? node.curThreadNum() : (int)(node.passQps());

}

       在这里,通过调用node.passQps()获取已经使用的token数量。

       点击passQps(),如下所示:

​​​​​​​passQps

public double passQps() {
    return rollingCounterInSecond.pass() / rollingCounterInSecond.getWindowIntervalInSec();
}

       在这里,rollingCounterInSecond对象保存了时间窗口对象的数组。pass()方法可以获取每个有效的时间窗口对象里已经使用的令牌数量,getWindowIntervalInSec()方法是时间窗口总长度,以秒为单位。两者相除就可以已使用的QPS。

       点击pass()方法,如下所示:

​​​​​​​pass

public long pass() {

        data.currentWindow();

        long pass = 0;

        List<MetricBucket> list = data.values();

        for (MetricBucket window : list) {

            pass += window.pass();

        }

        return pass;

    }

       在这里,会调用currentWindow()刷新当前窗口信息,然后累加每个窗口的计数值作为当前计数周期的计数值。

       点击currentWindow()方法,如下所示:

​​​​​​​currentWindow

public WindowWrap<T> currentWindow(long timeMillis) {

    int idx = calculateTimeIdx(timeMillis);

    long windowStart = calculateWindowStart(timeMillis);

    while (true) {

        WindowWrap<T> old = array.get(idx);

        if (old == null) {

            // 创建新窗口

            WindowWrap<T> window = new WindowWrap<>(windowLengthInMs, windowStart, newEmptyBucket());

            if (array.compareAndSet(idx, null, window)) {

                return window;

            }

        } else if (windowStart == old.windowStart()) {

            // 命中当前有效窗口

            return old;

        } else if (windowStart > old.windowStart()) {

            // 窗口已过期,重置并复用

            if (updateLock.tryLock()) {

                try {

                    return resetWindowTo(old, windowStart);

                } finally {

                    updateLock.unlock();

                }

            }

        }

    }

}

在这里:

  1. 获取当前时间窗口的索引
  2. 获取当前窗口的起始时间
  3. 根据当前时间窗口的索引,获取时间窗口对象,如果时间窗口对象为空,则创建一个新时间窗口对象;如果已经存在时间窗口对象,则返回该对象;如果时间窗口对象已过期,则重置并复用。

calculateTimeIdx

public int calculateTimeIdx(long timeMillis) {

    long timeId = timeMillis / windowLengthInMs;

    return (int)(timeId % array.length());

}

       在这里,根据当前时间戳计算对应窗口索引。

​​​​​​​calculateWindowStart

protected long calculateWindowStart(long timeMillis) {

    return timeMillis - timeMillis % windowLengthInMs;

}

       在这里,计算当前窗口的起始时间(对齐到窗口边界)。

       点击步骤pass的values()方法,如下所示:

​​​​​​​values

public List<T> values() {
    return values(TimeUtil.currentTimeMillis());
}
public List<T> values(long timeMillis) {
    if (timeMillis < 0) {
        return new ArrayList<T>();
    }
    int size = array.length();
    List<T> result = new ArrayList<T>(size);
    for (int i = 0; i < size; i++) {
        WindowWrap<T> windowWrap = array.get(i);
        if (windowWrap == null || isWindowDeprecated(timeMillis, windowWrap)) {
            continue;
        }
        result.add(windowWrap.value());
    }
    return result;
}

        在这里,循环时间窗口数组,忽略已经失效的时间窗口对象,将有效的时间窗口对象保存在一个列表对象里,并作为方法返回值进行返回。

​​​​​​​isWindowDeprecated

public boolean isWindowDeprecated(long time, WindowWrap<T> windowWrap) {
    return time - windowWrap.windowStart() > intervalInMs;
}

        在这里,将当前时间减去指定时间窗口对象的起始时间,如果结果大于计数周期时长,则表明指定的时间窗口对象已经失效。


文章转载自:

http://UUzpAQHF.fsjcn.cn
http://ZfdMEMQW.fsjcn.cn
http://iKeVp6bu.fsjcn.cn
http://CerZcpbH.fsjcn.cn
http://6OzyZrkd.fsjcn.cn
http://Vs4QfFT2.fsjcn.cn
http://bCsh3EgU.fsjcn.cn
http://2ga2PEI0.fsjcn.cn
http://jNzc2DyQ.fsjcn.cn
http://tyTMPRnX.fsjcn.cn
http://c9JUUKkz.fsjcn.cn
http://lgTmEiHS.fsjcn.cn
http://q0zuaAOj.fsjcn.cn
http://uRUbJRb3.fsjcn.cn
http://1782BW4l.fsjcn.cn
http://xfQIg0jY.fsjcn.cn
http://GoPn9wCX.fsjcn.cn
http://JJDGSPTA.fsjcn.cn
http://vtdZvDlB.fsjcn.cn
http://GBZHT1W0.fsjcn.cn
http://YPnKXZFG.fsjcn.cn
http://E68c6Nk4.fsjcn.cn
http://9tXagUJq.fsjcn.cn
http://4DVV8bFL.fsjcn.cn
http://SIauI3qu.fsjcn.cn
http://QPmt0Xgh.fsjcn.cn
http://9N9FglqA.fsjcn.cn
http://DYdF6jg5.fsjcn.cn
http://7InaUl2p.fsjcn.cn
http://oatI6Paa.fsjcn.cn
http://www.dtcms.com/wzjs/769855.html

相关文章:

  • 营销网站的特征手机网站建设的企业
  • 上杭县城乡规划建设局网站搜索网站的设计与建设
  • wordpress主题制作 工具网站的内部优化公司
  • 网站怎么收录到百度想要做个公司网站
  • 做网站的背景照设计一个商务网站
  • 网站建设公司生存现状wordpress用什么框架开发
  • 义乌建站网站开发公司电话
  • 靖江建设局网站世界各国o2o响应式网站
  • 电商网站建设内容网站城市切换代码
  • 外贸网站 球衣福州网站开发系列
  • 现在网站做多宽的微信小程序开发多少钱
  • 网站外包 博客网站编辑难做吗
  • 无锡网站制作建设郑州网站排名服务
  • 佛山高端网站制作舆情监控一般多少钱
  • 天津商务网站建设泉州市建设局网站
  • 个人网站搭建软件定制电商平台
  • html在线编程网站wordpress推送微信文章
  • 获取网站访客qq代码wordpress dux主题首页
  • 冷水滩城乡建设局网站建筑设计公司账务处理实例
  • 个人网站可以做论坛吗网站工程师是做什么的
  • 查找人网站 优帮云微平台图片
  • 做五金外贸哪个网站比较好wordpress 后台
  • 跨境电商在哪些网站上面做爱奇艺影业公司网站开发意义
  • 做丝网网站哪个好宝安设计网站建设
  • 零基础网站建设教学wordpress 两个数据库 互通
  • 青海网站建设公司多少钱北京php网站建设
  • 网站开发费 会计科目动易网站模版的制作
  • 网站建设对用户影响网站建设三秒原则
  • 判断网站是什么系统做的哪里去找做的好看的网站
  • 创建网站有免费的吗做阿里网站卖东西赚钱