Eureka的限流算法类RateLimiter是基于令牌桶算法来实现的,下面看一看令牌桶算法的原理:

需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码 一零三八七七四六二六

对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

源码解读:

package com.lovnx.web;import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;/*** @Class RateLimiter 实现基于令牌桶算法,有两个参数:* * @para  burstSize - 允许作为突发事件进入系统的最大请求数* @para  averageRate - 预期的每秒请求数(新版本也支持使用分钟为单位)* * @author lovnx*/
public class RateLimiter {//限流时间单位private final long rateToMsConversion;//当前可供消费的令牌数量private final AtomicInteger consumedTokens = new AtomicInteger();//上一次填充令牌的时间戳private final AtomicLong lastRefillTime = new AtomicLong(0);//限流时间单位可设置为TimeUnit.SECONDS,已废弃@Deprecatedpublic RateLimiter() {this(TimeUnit.SECONDS);}//限流时间单位可设置为TimeUnit.SECONDS或TimeUnit.MINUTESpublic RateLimiter(TimeUnit averageRateUnit) {switch (averageRateUnit) {case SECONDS:rateToMsConversion = 1000;break;case MINUTES:rateToMsConversion = 60 * 1000;break;default:throw new IllegalArgumentException("TimeUnit of " + averageRateUnit + " is not supported");}}//这个方法默认传的当前系统时间戳public boolean acquire(int burstSize, long averageRate) {return acquire(burstSize, averageRate, System.currentTimeMillis());}public boolean acquire(int burstSize, long averageRate, long currentTimeMillis) {//这里为了避免傻白甜将burstSize和averageRate设为负值而抛出异常if (burstSize <= 0 || averageRate <= 0) {return true;}//填充令牌refillToken(burstSize, averageRate, currentTimeMillis);//消费令牌成功与否return consumeToken(burstSize);}private void refillToken(int burstSize, long averageRate, long currentTimeMillis) {//得到上一次填充令牌的时间戳long refillTime = lastRefillTime.get();//时间间隔timeDelta = 传进来的时间戳currentTimeMillis - 上一次填充令牌的时间戳refillTimelong timeDelta = currentTimeMillis - refillTime;//计算出新的令牌数量newTokens = 时间间隔 * 平均速率 / 限流时间单位long newTokens = timeDelta * averageRate / rateToMsConversion;//如果新的令牌数量大于0个if (newTokens > 0) {//就等于上一次填充令牌的时间戳 + 新的令牌数量 * 限流时间单位 / 平均速率long newRefillTime = refillTime == 0? currentTimeMillis: refillTime + newTokens * rateToMsConversion / averageRate;//如果lastRefillTime内存偏移量值==上一次填充令牌的时间戳refillTime,则将lastRefillTime内存值设置为新的填充令牌时间戳newRefillTime//成功时进入条件体放令牌if (lastRefillTime.compareAndSet(refillTime, newRefillTime)) {//放令牌(核心代码)while (true) {//得到当前已消费的令牌数量currentLevelint currentLevel = consumedTokens.get();//获取校正令牌数量adjustedLevel,从当前已消费的令牌数量currentLevel和允许最大请求数burstSize间取小者,以防允许最大请求数burstSize变小//这一步和下一步叫做“流量削峰”int adjustedLevel = Math.min(currentLevel, burstSize);//获取新的令牌数量newLevel,0 与 (校正值 - 计算值)之间取大者int newLevel = (int) Math.max(0, adjustedLevel - newTokens);//如果当前已消费的令牌内存偏移量等于consumedTokens等于currentLevel,则将已消费的令牌量consumedTokens设置为新的令牌数量newLevel//终止放令牌,在已消费偏移量不等于currentLevel时循环计算,直到它们相等if (consumedTokens.compareAndSet(currentLevel, newLevel)) {return;}}}}}//消费令牌,传入突发量private boolean consumeToken(int burstSize) {//取令牌while (true) {//得到当前已消费的令牌数量currentLevelint currentLevel = consumedTokens.get();//如果已消费令牌量大于等于突发量,则不能消费令牌if (currentLevel >= burstSize) {return false;}//消费令牌,已消费令牌量+1if (consumedTokens.compareAndSet(currentLevel, currentLevel + 1)) {return true;}}}//重置令牌桶public void reset() {consumedTokens.set(0);lastRefillTime.set(0);}
}

java B2B2C Springboot多租户电子商城系统

java B2B2C Springboot多租户电子商城系统-Eureka源码解析...相关推荐

  1. java B2B2C Springboot多租户电子商城系统-spring-cloud-eureka-consumer...

    介绍 spring-cloud-eureka,更加具体的内容,这里将会介绍远程服务调用和及其负载均衡. 我们将我们的服务注册在我们的服务中心里,那么如何去调用这些服务呢?我们可以用使用远程服务调用来解 ...

  2. java B2B2C Springboot多租户电子商城系统-Spring Cloud Stream(消息驱动)

    1.什么是Spring Cloud Stream 愿意了解源码的朋友直接企鹅求求:二一四七七七五六三三 Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架.它可以基于 ...

  3. java B2B2C Springcloud多租户电子商城系统-消息驱动的微服务(消费分区)

    通过之前的学习,我们已经能够在多实例环境下,保证同一消息只被一个消费者实例进行接收和处理.但是,对于一些特殊场景,除了要保证单一实例消费之外,还希望那些具备相同特征的消息都能够被同一个实例进行消费.这 ...

  4. java B2B2C Springcloud多租户电子商城系统-spring-cloud-eureka

    介绍 spring-cloud-eureka,被动式的服务发现,统一监控和管理你的服务列表.电子商务平台源码请加企鹅求求:一零三八七七四六二六. 什么是服务发现? 服务发现就像聊天室一个,每个用户来的 ...

  5. java B2B2C Springcloud多租户电子商城系统-集成项目简介

    Spring Cloud集成项目有很多,下面我们列举一下和Spring Cloud相关的优秀项目,希望可以帮助到大家. Spring Cloud Config 配置管理工具包,让你可以把配置放到远程服 ...

  6. java B2B2C Springcloud多租户电子商城系统- Gateway 之Predict篇...

    predicate简介 Predicate来自于java8的接口.Predicate 接受一个输入参数,返回一个布尔值结果.该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与, ...

  7. java B2B2C Springcloud多租户电子商城系统-spring-cloud-eureka...

    介绍 spring-cloud-eureka,被动式的服务发现,统一监控和管理你的服务列表. 什么是服务发现? 服务发现就像聊天室一个,每个用户来的时候去服务器上注册,这样他的好友们就能看到你,你同时 ...

  8. java B2B2C Springcloud多租户电子商城系统-(七)高可用的分布式配置中心(Spring Cloud Config)...

    讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如下: 一. ...

  9. java B2B2C Springcloud多租户电子商城系统-docker-feign-hystrix-ribbon(七)

    2019独角兽企业重金招聘Python工程师标准>>> 简介 在上一节中,我们讨论了feign+hystrix在项目开发中,除了考虑正常的调用之外,负载均衡和故障转移也是关注的重点, ...

最新文章

  1. php 计算两点时间距离,PHP计算地球上两点之间的距离(示例详解)
  2. Mysql 的使用方式,挺全的够用了
  3. configure - 配置源代码树
  4. Win32 ASM 菜单编程Demo以及Win32 ASM 为什么需要等值定义
  5. 中文分词_中文分词最佳纪录刷新,两大模型分别解决中文分词及词性标注问题...
  6. 前端开发的浏览器知识
  7. android冒烟测试自动化,自动化冒烟测试脚本应当遵循的原则
  8. VTK:图像索贝尔Sobel用法实战
  9. Win11如何禁用USB端口?禁用USB端口的方法
  10. FutureTask源码解析(2)——深入理解FutureTask
  11. H5页面在自己APP中图标显示正常,接入钉钉请求.woff图标字体报错
  12. Flask留言板Demo
  13. 【安卓按键精灵自动取色(可用于比色,多点找色,找图实现)】
  14. 高中数学关于计算机的知识,高中数学必修三-算法概念基础知识解读
  15. Aandroid最简单最全面的热修复
  16. OkHttp超时时间设置
  17. C# .NET CORE在linux下读取图片加载到文档方法 Gdip libgdiplus
  18. Java 代码基于开源组件生成带头像的二维码,推荐收藏
  19. java 正确的表达式_JAVA程序设计课程作业,二、多选题1.指出正确的表达式A.double a=1.0B.Double a=new Dou...
  20. 扬帆凌远:shopee文具类的选品方法。

热门文章

  1. Hadoop问题:启动hadoop 2.6遇到的datanode启动不了
  2. Powershell 函数中的CmdletBinding()是怎么回事?
  3. java高质量图片压缩
  4. 转:华 为 路 由 常 用 命 令
  5. php读取大文件详解【OK】
  6. C++读取XML树的建立和遍历
  7. OCP DBA考证轻松过关详解(ZT)
  8. YAML出现严重的反序列化漏洞,谷歌TensorFlow将采用 JSON
  9. 苹果紧急修复三枚已遭在野利用的 iOS 0day
  10. 谷歌修复安卓System 组件中的多个 RCE 漏洞