上虞区建设局网站win10优化软件哪个好
2026/3/12 4:12:02 网站建设 项目流程
上虞区建设局网站,win10优化软件哪个好,公司的网站建设要记到什么科目,个人营业执照网上注册入口限流算法主要有如下几种#xff1a;基于信号量Semaphore 只有数量维度#xff0c;没有时间维度基于fixed window 带上了时间维度#xff0c;不过在两个窗口的临界点容易出现超出限流的情况#xff0c;比如限制每分钟10个请求#xff0c;在00:59请求了10次#xff0c;在01…限流算法主要有如下几种基于信号量Semaphore 只有数量维度没有时间维度基于fixed window 带上了时间维度不过在两个窗口的临界点容易出现超出限流的情况比如限制每分钟10个请求在00:59请求了10次在01:01又请求了10次而从00:30-01:30这个时间窗口来看这一分钟请求了20次没有控制好基于rolling window 就是要解决fixed window没解决的窗口临界问题主要有基于token bucket的算法以及基于leaky bucket的算法token 钱包 bucket算法 token按指定速率添加到bucket中 一个bucket有其容量限制超过其容量则多余的token会被丢弃 当请求到来时先试图获取token如果剩余token足够则放行不够则不允许放行(可能等待token足够再继续)2 简单实现2.1 Java版代码语言javascriptAI代码解释/** * The minimalistic token-bucket implementation */ public class MinimalisticTokenBucket { private final long capacity; private final double refillTokensPerOneMillis; private double availableTokens; private long lastRefillTimestamp; /** * Creates token-bucket with specified capacity and refill rate equals to refillTokens/refillPeriodMillis */ public MinimalisticTokenBucket(long capacity, long refillTokens, long refillPeriodMillis) { this.capacity capacity; this.refillTokensPerOneMillis (double) refillTokens / (double) refillPeriodMillis; this.availableTokens capacity; this.lastRefillTimestamp System.currentTimeMillis(); } synchronized public boolean tryConsume(int numberTokens) { refill(); if (availableTokens numberTokens) { return false; } else { availableTokens - numberTokens; return true; } } private void refill() { long currentTimeMillis System.currentTimeMillis(); if (currentTimeMillis lastRefillTimestamp) { long millisSinceLastRefill currentTimeMillis - lastRefillTimestamp; double refill millisSinceLastRefill * refillTokensPerOneMillis; this.availableTokens Math.min(capacity, availableTokens refill); this.lastRefillTimestamp currentTimeMillis; } } private static final class Selftest { public static void main(String[] args) { // 100 tokens per 1 second MinimalisticTokenBucket limiter new MinimalisticTokenBucket(100, 100, 1000); long startMillis System.currentTimeMillis(); long consumed 0; while (System.currentTimeMillis() - startMillis 10000) { if (limiter.tryConsume(1)) { consumed; } } System.out.println(consumed); } } }以上是bucket4j给出的一个简单实现用于理解token bucket算法。 这个算法没有采用线程去refill token因为bucket太多的话线程太多耗cpu 这个算法没有存储每个period使用的token设计了lastRefillTimestamp字段用于计算需要填充的token 每次tryConsume的时候方法内部首先调用refill根据设定的速度以及时间差计算这个时间段需要补充的token更新availableTokens以及lastRefillTimestamp 之后限流判断就是判断availableTokens与请求的numberTokens高性能限流器Guava RateLimiter令牌桶算法其核心是想通过限流器必须拿到令牌。 只要我们能够限制发放令牌的速率那么就能控制流速令牌以固定速率添加到令牌桶中假设限流速率是 r/秒则令牌每 1/r 秒会添加一个假设令牌桶的容量是 b 如果令牌桶已满则新的令牌会被丢弃请求能够通过限流器的前提是令牌桶中有令牌b 其实是burst的简写意义是限流器允许的最大突发流量。比如b10而且令牌桶中的令牌已满此时限流器允许10个请求同时通过限流器这只是突发流量这10个请求会带走10个令牌所以后续流量只能按照速率 r 通过限流器。如何实现呢基于生产者-消费者模式一个生产者线程定时向阻塞队列添加令牌试图通过限流器的线程则作为消费者线程只有从阻塞队列中获取到令牌才允许通过限流器设计看上去很完美实现也简单若并发量不大这没有什么问题。可使用限流大部分都是高并发场景而且系统压力已经临近极限了此时这个实现就有问题了。 问题出在定时器高并发下系统压力已临近极限定时器精度误差会很大定时器本身还会创建调度线程对系统性能影响极大。所以Guava没有使用定时器它是如何实现的呢Guava的令牌桶算法关键是记录并动态计算下一令牌的发放时间。 假设令牌桶的容量为 b1限流速率 r 1个请求/s。如下所示若当前令牌桶无令牌下一个令牌的发放时间是在第3s而在第2s时有个线程T1请求令牌此时该如何处理线程T1请求令牌对于该请求令牌的线程很显然需要等待1s1s以后第3s它就能拿到令牌。下一个令牌发放的时间也要增加1秒因为第3s发放的令牌已被线程T1预占。线程T1请求结束假设T1在预占第3s令牌后马上又有一个线程T2请求令牌线程T2请求令牌由于下一个令牌产生的时间是第4s所以线程T2要等待2s才能获取到令牌同时由于T2预占第4s令牌所以下一令牌产生时间还要增加1s线程T2请求结束线程T1、T2都是在下一令牌产生时间之前请求令牌若线程在下一令牌产生时间之后请求令牌会咋样 假设在线程T1请求令牌之后的5秒即第7秒线程T3请求令牌如下图所示。线程T3请求令牌由于第5s已产生一个令牌所以此时线程T3可直接拿到令牌无需等待。 在第7s实际上限流器能产生3个令牌第5、6、7秒各产生一个令牌。由于我们假设令牌桶的容量是1所以第6、7秒产生的令牌就丢弃了其实等价地你也可以认为是保留的第7秒的令牌丢弃的第5、6秒的令牌也就是说第7秒的令牌被线程T3占有了于是下一令牌的的产生时间应该是第8秒线程T3请求结束所以我们只需要记录一个下一令牌产生的时间并动态更新它。依然假设令牌桶的容量是1。关键是reserve()方法这个方法会为请求令牌的线程预分配令牌同时返回该线程能够获取令牌的时间。其实现逻辑就是上面提到的如果线程请求令牌的时间在下一令牌产生时间之后那么该线程立刻就能够获取令牌反之如果请求时间在下一令牌产生时间之前那么该线程是在下一令牌产生的时间获取令牌。由于此时下一令牌已经被该线程预占所以下一令牌产生的时间需要加上1秒。3 小结token bucket算法是基于QPS来限流其简单的实现就是计算单位时间补充token的速率然后每次tryConsume的时候根据速率修正availableTokens。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询