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

免费自助建站网站一览自助建站平台谷歌广告优化

免费自助建站网站一览自助建站平台,谷歌广告优化,网站建设用细节取胜,从事网站开发方向背景 近期在做调用第三方系统接口的业务场景时,经常会出现接口超时的问题,跟第三方系统一番扯皮后发现原来是他们做了限流,限制了我们一秒钟只能请求2次,所以需要我们自己做好限流,控制我们的请求频率。 令牌桶算法&a…

背景
近期在做调用第三方系统接口的业务场景时,经常会出现接口超时的问题,跟第三方系统一番扯皮后发现原来是他们做了限流,限制了我们一秒钟只能请求2次,所以需要我们自己做好限流,控制我们的请求频率。

令牌桶算法(Token Bucket Algorithm)是一种常用的流量控制和限流算法,广泛用于网络传输、API 限流、系统资源管理等场景中。它通过一个“桶”来模拟请求的处理能力,并以固定的速率往桶中放入令牌(token),只有拿到令牌的请求才能被处理。


🧠 基本原理

令牌桶算法的核心思想是:

  • 桶中可以存放一定数量的“令牌”。
  • 系统以固定速率往桶中添加令牌(比如每秒添加10个令牌)。
  • 当有请求到来时,必须从桶中取出一个令牌,如果桶中没有令牌,则请求被拒绝或等待。
  • 桶有容量上限,超过容量的令牌会被丢弃。

这样就可以限制请求的平均速率,同时允许一定程度的突发流量(因为桶中可以存储令牌)。


🔍 特点

特性描述
平均速率限制可以限制请求的平均速率
支持突发流量如果桶中有积压的令牌,可以在短时间内处理大量请求
实现简单逻辑清晰,容易实现
非阻塞可以选择是否等待令牌

📦 示例说明

假设我们有一个令牌桶:

  • 容量为 10 个令牌;
  • 每秒添加 2 个令牌;
  • 请求需要获取令牌才能执行。

场景举例:

  1. 正常情况:每秒最多处理 2 个请求;
  2. 空闲后突发:如果前几秒没有请求,桶里积累了多个令牌,这时可以处理突发的多个请求;
  3. 超出限制:当请求速度过快,桶中没有令牌时,后续请求将被拒绝。

💻 Java 实现示例

下面是两个简单的 Java 实现

非阻塞,获取不到令牌就直接拒绝:

import java.util.concurrent.atomic.AtomicLong;public class TokenBucket {// 每秒生成的令牌数private final long capacity;// 桶的最大容量private final long rate;// 当前令牌数量private AtomicLong tokens = new AtomicLong(0);// 上一次补充令牌的时间private long lastRefillTime = System.currentTimeMillis();public TokenBucket(long rate, long capacity) {this.rate = rate;this.capacity = capacity;this.tokens.set(capacity); // 初始填满}/*** 尝试获取一个令牌*/public synchronized boolean tryConsume() {refill();if (tokens.get() > 0) {tokens.decrementAndGet();return true;}return false;}/*** 根据时间差补充令牌*/private void refill() {long now = System.currentTimeMillis();long timeElapsed = now - lastRefillTime;// 计算应该补充的令牌数long tokensToAdd = (timeElapsed * rate) / 1000; // 毫秒转秒if (tokensToAdd > 0) {lastRefillTime = now;long newTokens = Math.min(tokens.get() + tokensToAdd, capacity);tokens.set(newTokens);}}public static void main(String[] args) throws InterruptedException {TokenBucket bucket = new TokenBucket(2, 5); // 每秒2个令牌,最多存5个for (int i = 0; i < 10; i++) {if (bucket.tryConsume()) {System.out.println("Request " + (i + 1) + " processed.");} else {System.out.println("Request " + (i + 1) + " rejected.");}Thread.sleep(200); // 模拟请求频率}}
}

阻塞,获取不到令牌就等待执行:

package org.ffjy.lld.ffcrm.common;import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.TimeUnit;public class TokenBucket {// 桶的最大容量private final long capacity;// 每秒生成的令牌数private final long rate;// 当前令牌数量private AtomicLong tokens = new AtomicLong(0);// 上一次补充令牌的时间private long lastRefillTime = System.currentTimeMillis();// 使用锁和条件变量实现等待机制private final Lock lock = new ReentrantLock();private final Condition notEmpty = lock.newCondition();public TokenBucket(long rate, long capacity) {this.rate = rate;this.capacity = capacity;this.tokens.set(capacity); // 初始填满}/*** 获取一个令牌,如果没有令牌则等待*/public void acquire() throws InterruptedException {lock.lock();try {while (true) {refill();if (tokens.get() > 0) {tokens.decrementAndGet();return;}// 计算需要等待的时间(毫秒)long now = System.currentTimeMillis();long timeUntilRefill = 1000 / rate; // 下一次补充令牌的时间间隔long waitTime = Math.max(0, lastRefillTime + timeUntilRefill - now);// 等待直到有新的令牌补充或超时notEmpty.await(waitTime, TimeUnit.MILLISECONDS);}} finally {lock.unlock();}}/*** 根据时间差补充令牌*/private void refill() {long now = System.currentTimeMillis();long timeElapsed = now - lastRefillTime;// 计算应该补充的令牌数long tokensToAdd = (timeElapsed * rate) / 1000; // 毫秒转秒if (tokensToAdd > 0) {lastRefillTime = now;long newTokens = Math.min(tokens.get() + tokensToAdd, capacity);tokens.set(newTokens);// 唤醒所有等待线程notEmpty.signalAll();}}public static void main(String[] args) throws InterruptedException {TokenBucket bucket = new TokenBucket(2, 5); // 每秒2个令牌,最多存5个for (int i = 0; i < 10; i++) {bucket.acquire();System.out.println("Request " + (i + 1) + " processed.");}}
}

⚙️ 与漏桶算法的区别(Guava 的 RateLimiter 使用的是平滑化的令牌桶)

对比项令牌桶漏桶
控制方式控制请求是否能拿取令牌控制请求流出的速度
流量特性允许突发流量强制平滑输出
实现复杂度简单较复杂
应用场景API限流、网络带宽控制需要严格控制输出速率的系统

🛠 实际应用

  • Spring Cloud Gateway / Zuul:做网关限流
  • Nginx:基于令牌桶实现请求限速
  • Guava RateLimiter:使用了改进版的令牌桶算法
  • 分布式系统限流:结合 Redis 实现分布式令牌桶

✅ 总结

令牌桶算法是一种非常实用的限流机制,具有以下优点:

  • 能够限制请求的平均速率
  • 支持一定的突发流量
  • 实现简单,性能好

在实际开发中,推荐结合使用如 Guava 的 RateLimiter 或 Spring Cloud Gateway 的限流组件,但在理解其背后原理(如令牌桶)之后,你可以根据业务需求进行定制化开发。

http://www.dtcms.com/a/559425.html

相关文章:

  • 模板网站定制网站建设门户网站需要注意什么意思
  • 网站建设那些公司比较好学院网站建设自查报告
  • 域名访问网站啥意思游戏币交易平台代理
  • 网站建设伍金手指下拉8可以做外链的图片网站
  • 网站维护工程师浙江建设工程信息网查询
  • 直播网站开发源码wordpress远程图片模块
  • 永清建设局网站网站开发的论文参考文献
  • 网站备案 更名学电商需要多少钱
  • 网站建设具体需求浙江省建设厅网站查询
  • 什么叫网站集约化建设网站如何吸引用户
  • 音乐网站开发与需求十大软件app排行榜下载
  • 网络网站如何推广网络营销推广方案策划书
  • 仿70网站分类目录源码招聘网站建设人员要求
  • 循环队列(不扩容)
  • 大连网站建设公司哪家好网站和网络有什么区别
  • plc学习路线
  • 网站页脚内容工具型网站
  • 网站制作费用多少wordpress mu 搜索
  • 建设网站的五个步骤个人网站主页建设教程
  • 行业平台网站建设一台服务器一个固定ip怎样做两个网站
  • 温州网站设计工作室优化推广网站淄博
  • 电子商务网站后台seo引擎搜索网站关键词
  • 酒店要做关于网站ppt怎么做保定网站建
  • 网站开发 外包空心wordpress识别手机跳转网站
  • wordpress可以仿任何站seo的工作流程
  • 微机课做网站广告案例网站
  • 还有哪些行业可以做垂直网站wordpress 仿百度百家
  • php7跨设备网站开发pdf网页首页设计图片
  • 网站设计人员就业要求青岛网站制作价格
  • 网站建设公司客户分析成都专业网站推广公司