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

常用的限流工具Guava RateLimiter 或Redisson RRateLimiter

在分布式系统和高并发场景中,限流是一个非常常见且重要的需求。以下是一些常用的限流工具和库,包括它们的特点和使用场景:

1. Guava RateLimiter

Google 的 Guava 库中的 RateLimiter 是一个简单且高效的限流工具,适用于单节点应用。

优点:

  • 易于使用
  • 高效

缺点:

  • 仅适用于单节点环境,不支持分布式限流

示例代码:

import com.google.common.util.concurrent.RateLimiter;public class GuavaRateLimiterExample {public static void main(String[] args) {// 创建一个每秒允许10个请求的RateLimiterRateLimiter rateLimiter = RateLimiter.create(10.0);for (int i = 0; i < 20; i++) {// 尝试获取一个许可if (rateLimiter.tryAcquire()) {System.out.println("Acquired permit " + (i + 1));// 执行限流操作} else {System.out.println("Could not acquire permit " + (i + 1));}}}
}

2. Redis + Lua 脚本

使用 Redis 和 Lua 脚本可以实现分布式限流,因为 Redis 本身是一个高性能的分布式缓存和存储系统。

优点:

  • 支持分布式
  • 高性能

缺点:

  • 实现复杂度较高,需要编写和维护 Lua 脚本

示例代码(Lua脚本):

local key = KEYS[1]
local limit = tonumber(ARGV[1])
local current = tonumber(redis.call('get', key) or "0")if current + 1 > limit thenreturn 0
elseredis.call("INCRBY", key, 1)redis.call("EXPIRE", key, 1)return 1
end

Java代码调用Lua脚本:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;public class RedisRateLimiter {private JedisPool jedisPool;public RedisRateLimiter(JedisPool jedisPool) {this.jedisPool = jedisPool;}public boolean tryAcquire(String key, int limit) {try (Jedis jedis = jedisPool.getResource()) {String luaScript = "..."; // 上述Lua脚本内容Object result = jedis.eval(luaScript, 1, key, String.valueOf(limit));return result.equals(1L);}}
}

3. Redisson RRateLimiter

Redisson 是一个基于 Redis 的 Java 客户端,提供了多种分布式数据结构和服务,其中包括 RRateLimiter 用于分布式限流。

优点:

  • 支持分布式
  • 使用方便,集成良好

缺点:

  • 依赖 Redis

示例代码:

import org.redisson.Redisson;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonRateLimiterExample {public static void main(String[] args) {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");RedissonClient redisson = Redisson.create(config);RRateLimiter rateLimiter = redisson.getRateLimiter("myRateLimiter");rateLimiter.trySetRate(RRateLimiter.RateType.OVERALL, 5, 1, RateIntervalUnit.SECONDS);for (int i = 0; i < 10; i++) {if (rateLimiter.tryAcquire()) {System.out.println("Acquired permit " + (i + 1));} else {System.out.println("Could not acquire permit " + (i + 1));}}redisson.shutdown();}
}
      <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId></dependency>spring:redis:redisson:config: |singleServerConfig:address: redis://xxxxx:6383connectionPoolSize: 30connectionMinimumIdleSize: 30password: xxxdatabase: 0connectTimeout: 1000timeout: 500retryAttempts: 3retryInterval: 1000threads: 10nettyThreads: 10transportMode: NIO@Component
@Configuration
public class XXXControlConfig {@Autowiredprivate RedissonClient redissonClient;@Autowiredprivate xxxControlProperties xxxControlProperties;/*** 拆章滑动窗口*/@Beanpublic RRateLimiter rateLimiter() {RRateLimiter rateLimiter = redissonClient.getRateLimiter("xxx");rateLimiter.trySetRate(RateType.OVERALL,flowControlProperties.getRate().getInterval(),flowControlProperties.getRate().getPermits(),RateIntervalUnit.MINUTES);return rateLimiter;}/*** 试听最大并发数*/@Beanpublic RSemaphore semaphore() {RSemaphore semaphore = redissonClient.getSemaphore("xxxxx");semaphore.trySetPermits(flowControlProperties.getSemaphore().getPermits());return semaphore;}@Autowiredprivate RRateLimiter rateLimiter;if(flowControlProperties.getRate().isEnabled() && !rateLimiter.tryAcquire()) {throw new SystemException(Code, "系统繁忙,请稍后再试");}

4. Bucket4j

Bucket4j 是一个 Java 限流库,提供了灵活的令牌桶算法实现,可用于本地或分布式限流(通过第三方存储如 Hazelcast)。

优点:

  • 灵活
  • 支持多种存储后端

缺点:

  • 配置相对复杂

示例代码:

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;import java.time.Duration;public class Bucket4jExample {public static void main(String[] args) {Bandwidth limit = Bandwidth.classic(10, Refill.greedy(10, Duration.ofSeconds(1)));Bucket bucket = Bucket4j.builder().addLimit(limit).build();for (int i = 0; i < 20; i++) {if (bucket.tryConsume(1)) {System.out.println("Acquired permit " + (i + 1));} else {System.out.println("Could not acquire permit " + (i + 1));}}}
}

这些工具各有优缺点,可以根据你的具体需求选择合适的限流工具。如果你需要分布式限流,推荐使用 Redis 相关的解决方案,如 Redisson 或者自定义 Lua 脚本。如果是单节点应用,Guava 的 RateLimiter 或 Bucket4j 都是不错的选择。

相关文章:

常用的限流工具Guava RateLimiter 或Redisson RRateLimiter

在分布式系统和高并发场景中&#xff0c;限流是一个非常常见且重要的需求。以下是一些常用的限流工具和库&#xff0c;包括它们的特点和使用场景&#xff1a; 1. Guava RateLimiter Google 的 Guava 库中的 RateLimiter 是一个简单且高效的限流工具&#xff0c;适用于单节点应…...

卷积神经网络(CNN)和循环神经网络(RNN) 的区别与联系

卷积神经网络&#xff08;CNN&#xff09;和循环神经网络&#xff08;RNN&#xff09;是两种广泛应用于深度学习的神经网络架构&#xff0c;它们在设计理念和应用领域上有显著区别&#xff0c;但也存在一些联系。 ### 卷积神经网络&#xff08;CNN&#xff09; #### 主要特点…...

Unity【入门】场景切换和游戏退出及准备

1、必备知识点场景切换和游戏退出 文章目录 1、必备知识点场景切换和游戏退出1、场景切换2、鼠标隐藏锁定相关3、随机数和自带委托4、模型资源的导入1、模型由什么构成2、Unity支持的模型格式3、如何指导美术同学导出模型4、学习阶段在哪里获取模型资源 2、小项目准备工作需求分…...

Python 函数递归

以下是一个使用递归计算阶乘的 Python 函数示例 &#xff1a; 应用场景&#xff1a; 1. 动态规划问题&#xff1a;在一些需要逐步求解子问题并利用其结果的动态规划场景中&#xff0c;递归可以帮助直观地表达问题的分解和求解过程。 2. 遍历具有递归结构的数据&#xff1a;如递…...

MyBatis(27)如何配置 MyBatis 实现打印可执行的 SQL 语句

在开发过程中&#xff0c;打印可执行的SQL语句对于调试和性能优化是非常有帮助的。MyBatis提供了几种方式来实现SQL语句的打印。 1. 使用日志框架 MyBatis可以通过配置其内部使用的日志框架&#xff08;如Log4j、Logback等&#xff09;来打印SQL语句。这是最常用的方法。 Lo…...

3.js - 裁剪平面(clipIntersection:交集、并集)

看图 代码 // ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import …...

在5G/6G应用中实现高性能放大器的建模挑战

来源&#xff1a;Modelling Challenges for Enabling High Performance Amplifiers in 5G/6G Applications {第28届“集成电路和系统的混合设计”(Mixed Design of Integrated Circuits and Systems)国际会议论文集&#xff0c;2021年6月24日至26日&#xff0c;波兰洛迪} 本文讨…...

Perl 数据类型

Perl 数据类型 Perl 是一种功能丰富的编程语言&#xff0c;广泛应用于系统管理、网络编程、GUI 开发等领域。在 Perl 中&#xff0c;数据类型是编程的基础&#xff0c;决定了变量存储信息的方式以及可以对这些信息执行的操作。本文将详细介绍 Perl 中的主要数据类型&#xff0…...

网络协议 -- IP、ICMP、TCP、UDP字段解析

网络协议报文解析及工具使用介绍 1. 以太网帧格式及各字段作用 -------------------------------- | Destination MAC Address (48 bits) | -------------------------------- | Source MAC Address (48 bits) …...

【工具】豆瓣自动回贴软件

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 相比于之前粗糙丑陋的黑命令框版本&#xff0c;这个版本新增了UI界面&#xff0c;从此可以不需要再挨个去翻配置文件了。 另外&#xff0c;升级了隐藏浏…...

初学Spring之动态代理模式

动态代理和静态代理角色一样 动态代理的代理类是动态生成的 动态代理分为两大类&#xff1a; 基于接口的动态代理&#xff08;JDK 动态代理&#xff09;、基于类的动态代理&#xff08;cglib&#xff09; 也可以用 Java 字节码实现&#xff08;Javassist&#xff09; Prox…...

Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类

Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类 1 安装Visual studio 20203,并安装插件1.1 下载并安装 Visual Studio1.2 步骤二:安装 installer projects 扩展插件2 创建安装项目2.1 创建Windows安装项目2.2 新建应用程序安装文件夹2.3 添加…...

vue学习笔记(购物车小案例)

用一个简单的购物车demo来回顾一下其中需要注意的细节。 先看一下最终效果 功能&#xff1a; &#xff08;1&#xff09;全选按钮和下面的商品项的选中状态同步&#xff0c;当下面的商品全部选中时&#xff0c;全选勾选&#xff0c;反之&#xff0c;则不勾选。 &#xff08…...

昇思25天学习打卡营第19天 | RNN实现情感分类

RNN实现情感分类 概述 情感分类是自然语言处理中的经典任务&#xff0c;是典型的分类问题。本节使用MindSpore实现一个基于RNN网络的情感分类模型&#xff0c;实现如下的效果&#xff1a; 输入: This film is terrible 正确标签: Negative 预测标签: Negative输入: This fil…...

【VUE基础】VUE3第三节—核心语法之ref标签、props

ref标签 作用&#xff1a;用于注册模板引用。 用在普通DOM标签上&#xff0c;获取的是DOM节点。 用在组件标签上&#xff0c;获取的是组件实例对象。 用在普通DOM标签上&#xff1a; <template><div class"person"><h1 ref"title1">…...

生物化学笔记:电阻抗基础+电化学阻抗谱EIS+电化学系统频率响应分析

视频教程地址 引言 方法介绍 稳定&#xff1a;撤去扰动会到原始状态&#xff0c;反之不稳定&#xff0c;还有近似稳定的 阻抗谱图形&#xff08;Nyquist和Bode图&#xff09; 阻抗谱图形是用于分析电化学系统和材料的工具&#xff0c;主要有两种类型&#xff1a;Nyquist图和B…...

SQL使用join查询方式找出没有分类的电影id以及名称

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 现有电影信息…...

对MsgPack与JSON进行序列化的效率比较

序列化是将对象转换为字节流的过程&#xff0c;以便在内存或磁盘上存储。常见的序列化方法包括MsgPack和JSON。以下将详细探讨MsgPack和JSON在序列化效率方面的差异。 1. MsgPack的效率&#xff1a; 优点&#xff1a; 高压缩率&#xff1a; MsgPack采用高效的二进制编码格式&…...

Unix\Linux 执行shell报错:“$‘\r‘: 未找到命令” 解决

linux执行脚本sh xxx.sh报错&#xff1a;$xxx\r: 未找到命令 原因&#xff1a;shell脚本在Windows编写导致的换行问题&#xff1a; Windows 的换行符号为 CRLF&#xff08;\r\n&#xff09;&#xff0c;而 Unix\Linux 为 LF&#xff08;\n&#xff09;。 缩写全称ASCII转义说…...

动态路由--RIP配置(思科cisco)

一、简介 RIP协议&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的动态路由选择协议。 在RIP协议中&#xff0c;如果路由器A和网络B直接相连&#xff0c;那么路由器A到网络B的距离被定义为1跳。若从路由器A出发到达网络B需要…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...