基于JAVA的Dubbo 实现的各种限流算法

在基于 Java 的 Dubbo 实现中,限流(Rate Limiting)同样是一个关键的需求。Dubbo 是阿里巴巴开源的一款高性能 Java RPC 框架,广泛应用于分布式服务架构中。实现限流可以帮助服务在高并发场景下保持稳定性和可靠性。以下是几种常见的限流算法及其在 Dubbo 中的实现方法:

 

1. 固定窗口算法 (Fixed Window Algorithm)

固定窗口算法将时间划分为固定长度的窗口,并在每个窗口内限制请求数。

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;public class FixedWindowRateLimiter {private final ConcurrentHashMap<Long, AtomicInteger> windows = new ConcurrentHashMap<>();private final int limit;private final long windowSizeInMillis;public FixedWindowRateLimiter(int limit, long windowSizeInMillis) {this.limit = limit;this.windowSizeInMillis = windowSizeInMillis;}public boolean allowRequest() {long currentWindow = System.currentTimeMillis() / windowSizeInMillis;windows.putIfAbsent(currentWindow, new AtomicInteger(0));return windows.get(currentWindow).incrementAndGet() <= limit;}
}

2. 滑动窗口算法 (Sliding Window Algorithm)

滑动窗口算法将固定窗口进一步划分为更小的时间片,从而更精确地控制流量。
 

import java.util.LinkedList;
import java.util.Queue;public class SlidingWindowRateLimiter {private final Queue<Long> requestTimestamps = new LinkedList<>();private final int limit;private final long windowSizeInMillis;public SlidingWindowRateLimiter(int limit, long windowSizeInMillis) {this.limit = limit;this.windowSizeInMillis = windowSizeInMillis;}public synchronized boolean allowRequest() {long now = System.currentTimeMillis();while (!requestTimestamps.isEmpty() && requestTimestamps.peek() <= now - windowSizeInMillis) {requestTimestamps.poll();}if (requestTimestamps.size() < limit) {requestTimestamps.add(now);return true;}return false;}
}

3. 令牌桶算法 (Token Bucket Algorithm)

令牌桶算法允许突发流量,并在平稳流量时重新填充令牌。

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;public class TokenBucketRateLimiter {private final int maxTokens;private final int refillRate;private final AtomicInteger tokens;private final ScheduledExecutorService scheduler;public TokenBucketRateLimiter(int maxTokens, int refillRate) {this.maxTokens = maxTokens;this.refillRate = refillRate;this.tokens = new AtomicInteger(maxTokens);this.scheduler = Executors.newScheduledThreadPool(1);scheduler.scheduleAtFixedRate(this::refill, 1, 1, TimeUnit.SECONDS);}public boolean allowRequest() {if (tokens.get() > 0) {tokens.decrementAndGet();return true;}return false;}private void refill() {if (tokens.get() < maxTokens) {tokens.incrementAndGet();}}
}

4. 漏桶算法 (Leaky Bucket Algorithm)

漏桶算法以恒定速率处理请求,适用于平滑流量,防止流量突发。

import java.util.concurrent.atomic.AtomicInteger;public class LeakyBucketRateLimiter {private final int capacity;private final long leakRateInMillis;private final AtomicInteger waterLevel;private long lastLeakTime;public LeakyBucketRateLimiter(int capacity, long leakRateInMillis) {this.capacity = capacity;this.leakRateInMillis = leakRateInMillis;this.waterLevel = new AtomicInteger(0);this.lastLeakTime = System.currentTimeMillis();}public synchronized boolean allowRequest() {leak();if (waterLevel.get() < capacity) {waterLevel.incrementAndGet();return true;}return false;}private void leak() {long now = System.currentTimeMillis();long elapsedTime = now - lastLeakTime;int leaked = (int) (elapsedTime / leakRateInMillis);if (leaked > 0) {waterLevel.addAndGet(-leaked);if (waterLevel.get() < 0) {waterLevel.set(0);}lastLeakTime = now;}}
}

在 Dubbo 中集成限流器

要在 Dubbo 中集成限流器,可以通过实现自定义的过滤器。以下是一个简单的示例,展示如何将限流器集成到 Dubbo 过滤器中:

自定义过滤器
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;@Activate(group = {"provider"})
public class RateLimitingFilter implements Filter {private final FixedWindowRateLimiter rateLimiter = new FixedWindowRateLimiter(100, 1000);@Overridepublic Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {if (rateLimiter.allowRequest()) {return invoker.invoke(invocation);} else {throw new RpcException(RpcException.LIMIT_EXCEEDED, "Rate limit exceeded");}}
}
配置 Dubbo 使用自定义过滤器

在 Dubbo 的配置文件中添加自定义过滤器:

<dubbo:provider filter="rateLimitingFilter" />

或者在 Spring 配置文件中添加:

<dubbo:provider><dubbo:parameter key="filter" value="rateLimitingFilter" />
</dubbo:provider>

通过以上方式,可以在 Dubbo 中实现各种限流算法,从而有效控制请求流量,保护服务稳定性。根据具体的业务需求,选择合适的限流算法,确保系统的性能和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/13506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux进程调度与切换、环境变量

文章目录 Linux优先级Linux的调度与切换**进程切换**&#xff1a;**进程调度**&#xff1a;优先级活动队列过期队列active指针和expired指针 环境变量main函数参数 int main(int argc, char *argv[], char *envp[]) 环境变量环境变量和本地变量echo查看单个环境变量的方法expor…

蓝牙模块在无人机 ID识别、标准制定发挥的作用及其应用优势和面临的挑战

随着科技的飞速发展&#xff0c;无人机已经广泛应用于航拍、农业、救援、物流等多个领域。而在无人机的通信与控制系统中&#xff0c;蓝牙模块扮演着重要的角色。本文将探讨蓝牙模块在无人机Remote ID识别和标准制定执行中发挥的作用&#xff0c;并分析其应用优势和面临的挑战。…

Java读取串口及端口调试

本篇主要讲述使用Java对串口进行读取和发送操作 准备 在项目中导入第三方Jar包 Jar包已经在资源中绑定&#xff0c;或者去官网上自行下载jSerialComm 注意当前jar包是配合JDK1.8环境使用&#xff0c;如果是1.8以下程序将直接中断 安装虚拟串口的软件 Configure Virtual Seri…

一款功能强大的安卓虚拟机应用——VMOS Pro使用分享

前段时间我刚刚分享一个WeChat平板模块能够允许用户自由修改系统设置&#xff0c;让你的Android备用手机焕发新生&#xff0c;实现手机PAD化&#xff0c;实现两台设备同时登录微信号。今天我分享的这个相比WeChat更为简单&#xff0c;因为它可以通过虚拟机的方式进行多种androi…

分类和品牌关联

文章目录 1.数据库表设计1.多表关联设计2.创建表 2.使用renren-generator生成CRUD1.基本配置检查1.generator.properties2.application.yml 2.生成代码1.进入localhost:81生成代码2.将main目录覆盖sunliving-commodity模块的main目录 3.代码检查1.注释掉CategoryBrandRelationC…

JavaWeb基础(HTML,CSS,JS)

这些知识用了三四天左右学完&#xff0c;因为是JavaWeb&#xff0c;并不是前端&#xff0c;所以只是够用&#xff0c;不是深入&#xff0c;但是这确实是学校一个学期交的东西&#xff08;JavaWeb课程&#xff09;。 总结一下网页分为三部分&#xff1a;HTML(内容结构),CSS&…

MySql--SQL语言

目录 SQl---DDL 结构定义 创建、删除 数据库 代码 运行 设计表 数据类型 整数 浮点数 主键 约束 主键自增长 默认值 字段注释 创建、删除 表 代码 运行 代码 代码 运行 SQL---DML 数据操纵 插入数据 代码 运行 代码 运行 代码 运行 代码 …

【实战教程】使用Spring AOP和自定义注解监控接口调用

一、背景 随着项目的长期运行和迭代&#xff0c;积累的功能日益繁多&#xff0c;但并非所有功能都能得到用户的频繁使用或实际上根本无人问津。 为了提高系统性能和代码质量&#xff0c;我们往往需要对那些不常用的功能进行下线处理。 那么&#xff0c;该下线哪些功能呢&…

docker部署kafka实战

目录 一、部署kafaka、zookeeper 二、测试信息发送与接收 三、kafka进阶 一、部署kafaka、zookeeper 请提前安装docker、docker-compose 安装docker&#xff1a;docker--安装docker-ce-CSDN博客 安装docker-compose&#xff1a; 安装docker-compose_安装 docker-compose-CSD…

云下到云上,丽迅物流如何实现数据库降本50% | OceanBase案例

在2024年3月20日的首场OceanBase数据库城市行活动中&#xff0c;专注于物流及供应链解决方案的丽迅物流的架构师阳磊&#xff0c;围绕“OB Cloud在丽迅物流的实践”这一主题&#xff0c;进行了精彩的演讲。本文为此次演讲的内容回顾。 在丽迅物流&#xff08;Lesoon Logistics…

9.1 Go语言入门(环境篇)

Go语言入门&#xff08;环境篇&#xff09; 目录一、什么是Go语言二、下载安装配置Go语言开发环境1. 下载2. 安装3. 配置环境变量4. 安装环境验证 三、 开发工具1. 下载2. 安装3. 激活4. 配置SDK 四、 创建go工程文件并运行1. 创建go工程2. 示例代码3. 运行代码 目录 一、什么…

软件开源协议与QT的开源协议介绍

一.常见的六种开源协议 1.BSD协议 BSD协议全称为“Berkely Software Distribution”&#xff0c;中文译为“伯克利软件发行版”。其最早用于伯克利UNIX操作系统上的开源贡献。 主要特点&#xff1a; 允许修改源码 允许源码再发布 允许商业软件发布和销售 约束&#xff1…

shell 脚本笔记2

3.env与set区别 env用于查看系统环境变量 set用于查看系统环境变量自定义变量函数 4.常用环境变量 变量名称含义PATH命令搜索的目录路径, 与windows的环境变量PATH功能一样LANG查询系统的字符集HISTFILE查询当前用户执行命令的历史列表 Shell变量&#xff1a;自定义变量 目标…

HCIP【VRRP、MSTP、VLAN综合实验】

目录 一、实验拓扑图&#xff1a; ​编辑二、实验要求 三、实验思路 四、实验步骤 &#xff08;1&#xff09; eth-trunk技术配置 &#xff08;2&#xff09;vlan 技术配置 &#xff08;3&#xff09;配置SW1、SW2、AR1、ISP的IP地址 &#xff08;4&#xff09;在交换机…

FBB-Frontiers in Bioengineering and Biotechnology

文章目录 一、期刊简介二、征稿信息三、期刊表现四、投稿须知五、投稿咨询 一、期刊简介 Frontiers in Bioengineering and Biotechnology是专注生物工程和生物技术领域的开放获取期刊。 研究范围涵盖生物材料、生物力学、生物工艺工程、生物安全和生物安保&#xff0c;生物传…

QT项目-欢乐斗地主游戏

QT项目-欢乐斗地主游戏 游戏概述游戏规则牌型牌型的大小游戏角色游戏规则游戏的胜负游戏计分规则 游戏相关的类介绍卡牌类玩家类窗口类游戏控制类游戏策略类线程类音频类 游戏主要组件卡牌玩家窗口 游戏控制源码 游戏概述 游戏规则 不同地域游戏规则可能有些许差异&#xff0c…

MySQL之Schema与数据类型优化(三)

Schema与数据类型优化 BLOB和TEXT类型 BLOB和TEXT都是为存储很大的数据而设计的字符串数据类型&#xff0c;分别采用二进制和字符方式存储。 实际上它们分别属于两组不同的数据类型家族:字符类型是TINYTEXT&#xff0c;SMALLTEXT,TEXT&#xff0c;MEDIUMTEXT&#xff0c;LONG…

Spring Cloud整合Sentinel

1、引入依赖 链接: 点击查看依赖关系 父pom <spring.cloud.version>Hoxton.SR12</spring.cloud.version> <spring.cloud.alibaba.version>2.2.10-RC1</spring.cloud.alibaba.version>Sentinel应用直接引用starter <dependency><groupId&…

【UE5.1】* 动画重定向 (让你的角色可以使用小白人全部动画)

前言 这里以小白人动画重定向给商城资产“Adventure Character”中的角色为例&#xff0c;阐述如何使用UE5.1进行动画重定向。 步骤 1. 创建一个IK绑定 这里选择小白人的骨骼网格体 这里命名为“IKRig_Mannequin” 2. 再新建一个IK绑定&#xff0c;这里使用你要替换给的角色…

MyBatis入门——MyBatis XML配置文件(3)

目录 一、配置连接字符串和MyBatis 二、写持久层代码 1、添加 mapper 接口 2、添加 USerInfoXmlMapper.xml 3、测试类代码 三、增删改查操作 1、增&#xff08;Insert&#xff09; 返回自增 id 2、删&#xff08;Delete&#xff09; 3、改&#xff08;update&#xf…