基于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);

    @Override
    public 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 中实现各种限流算法,从而有效控制请求流量,保护服务稳定性。根据具体的业务需求,选择合适的限流算法,确保系统的性能和可靠性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PostgresSQL开启归档模式

文章目录 一、查询数据库归档是否开启1、查看数据目录(找出conf文件位置)2、查看归档是否开启 二、开启归档模式&#xff08;开启后有一定的性能损耗&#xff09;1、创建归档目录2、修改postgresql.conf配置文件3、重启pg 三、验证归档情况1、查看归档是否开启2、检查点 , 刷新…

04-Json/Ajax/Vue的知识

1. Json结构 1.1 Json概述 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;实现数据前后端交互。 它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。 JSON采用完全独立于程序语言的文本格式。这些特性使JSON成为理想的数据交换…

前端 CSS 经典:好看的标题动画

前言&#xff1a;好看的标题动画实现。 效果&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><…

注意力机制篇 | MSFE:即插即用的多尺度滑窗注意力(附源码实现)

前言:Hello大家好,我是小哥谈。多尺度滑窗注意力(Multi-Scale Sliding Window Attention,MSFE)是一种用于处理图像的深度学习模型。它通过引入多尺度特征提取和滑窗注意力机制来提高图像识别的准确性。在MSFE中,模型采用多尺度卷积神经网络来提取图像的特征,然后使用滑窗…

3d数字化虚拟交互展厅让您紧跟时代的步伐

虚实融合打破边界&#xff0c;北京VR虚拟数字展厅搭建让体验者彷如置身于一部三维电影中&#xff0c;可以对场景中的物体、角色、模型进行自由参观和体验&#xff0c;并且系统支持随时更新&#xff0c;让您紧跟时代的步伐&#xff0c;领略更新的展览风采。 除了常见的科普培训&…

服务端Web资源缓存

1.前言 虽然客户端缓存效果很好&#xff0c;但它有一个核心问题&#xff1a;要在本地提供资源&#xff0c;必须先将其存储在缓存中。因此&#xff0c;每个客户端都需要其缓存的资源。如果请求的资源需要大量计算&#xff0c;则无法扩展。服务器端缓存背后的理念是计算一次资源…

Eclipse下载安装教程(包含JDK安装)【保姆级教学】【2024.4已更新】

目录 文章最后附下载链接 第一步&#xff1a;下载Eclipse&#xff0c;并安装 第二步&#xff1a;下载JDK&#xff0c;并安装 第三步&#xff1a;Java运行环境配置 安装Eclipse必须同时安装JDK &#xff01;&#xff01;&#xff01; 文章最后附下载链接 第一步&#xf…

高校多云资源统一管理和监控解决方案

项目背景与业务场景 随着云计算技术不断发展更新&#xff0c;高校科研用户对云服务需求不断提高&#xff0c;科研又是基础创新的来源&#xff0c;但算力少、共享难、不好用一直是科研的突出问题。小的科研团队经费少设备少&#xff0c;中型的科研团队设备有限&#xff0c;高峰…

【企业动态】东胜物联成为AWS硬件合作伙伴,助力实现边缘智能

近日&#xff0c;AIoT硬件设备供应商东胜物联与全球领先的云计算服务提供商亚马逊云&#xff08;AWS&#xff09;达成合作关系&#xff0c;共同致力于推动物联网技术的发展&#xff0c;为企业客户提供更智能、灵活的硬件解决方案&#xff0c;助力智能化升级和数字化转型。 作为…

Vue3刷新页面后404,需要配置IIS的URL重写

Vue3刷新页面后404&#xff0c;需要配置IIS的URL重写 1.下载IIS重写工具 https://download.csdn.net/download/cplvfx/89331452 2.IIS的Url配置 安装后IIS会显示《URL重写》 选中你的站点 点击重写 点击《增加规则》 点击-空白规则 2.1匹配URL 请求的URL&#xff1a; 选择…

ArcGIS批量更改所有符号的格式

这期谈一下&#xff0c;如何修改所有符号的样式。 比如&#xff0c;我们需要更改下图的面符号位无轮廓的 该如何批量修改的呢&#xff1f; 视频教学吧&#xff1a; ArcGIS批量更改所有符号的格式 ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放-CSDN博客文章浏览阅…

MavLinK协议

由于在公司需要使用这个&#xff0c;我就写一个文章用于入门级别 简单介绍 MAVSDK是PX4开源团队贡献的基于mavlink通信协议的用于无人机应用开发的SDK&#xff0c;其可以部署在Windows、Linux、Android等多种平台&#xff0c;并且支持多种语言如c/c、python、Java等。 在官网…

Docker-数据卷的挂载

文章目录 数据卷概念数据卷实现机制数据卷特性数据卷操作数据卷挂载通用命令匿名挂载具名挂载数据卷继承容器数据卷只读容器数据卷读写-默认 总结 数据卷概念 为了很好的实现数据保存和数据共享&#xff0c;Docker提出了Volume这个概念&#xff0c;简单的说就是绕过默认的联合文…

【手写大跟堆详解】

文章目录 大跟堆介绍大跟堆的结构大跟堆的应用场景大跟堆的代码实现 大跟堆介绍 大根堆&#xff08;Max Heap&#xff09;是一种特殊的二叉树结构&#xff0c;它满足以下两个条件&#xff1a; 1.完全二叉树&#xff1a;大根堆是一棵完全二叉树&#xff0c;即除了最后一层外&am…

ORACLE 资源管理参数与等待事件resmgr:cpu quantum

RESOURCE_MANAGER_PLAN 先来看下参数的含义 官网链接&#xff1a;RESOURCE_MANAGER_PLAN (oracle.com) 意思翻译过来这个参数用于资源计划。后边的看完也不是很明白具体的作用 于是参考了以下文章 Oracle 参数 RESOURCE_MANAGER_PLAN 官方解释&#xff0c;作用&#xff0c;…

Kubernetes——Pod详解

目录 一、Pod基础概念 1.概念 2.使用方式 3.Pause容器 3.1网络 3.2存储 4.Pod容器分类 4.1自主式Pod 4.2控制器管理的Pod 二、Pod的分类 1.基础容器&#xff08;infrastructure container&#xff09; 2.初始化容器&#xff08;initcontainers&#xff09; 2.1Ini…

前端vue用el-table如何实现表头内容过长换行处理,实现换行效果

前端vue用el-table如何实现表头内容过长换行处理&#xff0c;实现换行效果 这是效果图 有两种方法&#xff0c;一种简易版本&#xff0c;一种万能方法,都是el-table&#xff0c;先看文档 表头标题是可以自定义的 方法一 label的解释写在代码里面了&#xff0c;这里会自动形成换…

Edge浏览器“此页存在问题”解决思路

Edge浏览器显示“此页存在问题”解决思路 大家平时使用Edge浏览器时&#xff0c;是否和我一样会突然出现“此页存在问题”的情况&#xff1f; 经过百度查询后我找了一种情况和解决办法&#xff0c;能够大大减少这类问题的出现。出现“此页存在问题”可能是因为之前使用过软件…

C++相关概念和易错语法(13)(string的模拟实现)

string由于存在字符串和单字符的概念&#xff0c;使得它的一些接口&#xff0c;实现要比vector多一些。本质上来看string的实现是在顺序表的基础上加入串相关的操作。下面我会分享如何模拟实现string&#xff0c;这可以进一步提高我们对string的熟练程度。 1.构造函数、拷贝构…

Mysql与Navicat可视化命令大全 ----项目实战

软件准备&#xff1a;✍Mysql8.0下载地址&#xff08;推荐&#xff09;✍Navicat 16 下载地址&#xff08;推荐&#xff09; 注&#xff1a;不会安装看主页&#xff0c;关注我&#xff0c;免费指导&#xff0c;接计算机毕设☑ -----------------------------------------------…