【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的限流器RateLimiter功能服务

简介: 随着互联网的快速发展,越来越多的应用程序需要处理大量的请求。如果没有限制,这些请求可能会导致应用程序崩溃或变得不可用。因此,限流器是一种非常重要的技术,可以帮助应用程序控制请求的数量和速率,以保持稳定和可靠的运行。

限流器的算法选项

随着互联网的快速发展,越来越多的应用程序需要处理大量的请求。如果没有限制,这些请求可能会导致应用程序崩溃或变得不可用。因此,限流器是一种非常重要的技术,可以帮助应用程序控制请求的数量和速率,以保持稳定和可靠的运行。

Java是一种非常流行的编程语言,具有广泛的应用场景。在Java中,实现限流器的方法有很多种。本文将介绍一些常见的实现方法和技术。

令牌桶算法

令牌桶算法是一种常见的限流算法,它基于一个令牌桶来控制请求的速率。在令牌桶算法中,令牌桶以固定的速率生成令牌,并将这些令牌存储在桶中。每当一个请求到达时,它必须从桶中获取一个令牌才能被处理。如果桶中没有足够的令牌,请求将被拒绝。

在Java中,可以使用Guava库中的RateLimiter类来实现令牌桶算法。RateLimiter类提供了一种简单而有效的方式来控制请求的速率。

接下来我们开发带着大家手把手去实现一个属于我们自己的限流器服务组件。

开发阶段

Maven的依赖配置

首先,我们需要开始配置Maven所具有的依赖关系,主要包含者基础的工具类配置信息包含了Hutools和apache-commons相关的
基础工具组件,以及针对于我们的限流器的服务库Guava。

   <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
           <dependency>
            <groupId>com.fengwenyi</groupId>
            <artifactId>JavaLib</artifactId>
            <version>2.1.6</version>
        </dependency>        
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <!--joda-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0-jre</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.8</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
         <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>        
    </dependencies>

核心服务类之间的关系

主要包含了各个服务类之间的关系,包含了继承关系以及服务功能的继承总览机制。
在这里插入图片描述

定义限流器基础接口

首先,我们先定义一下我们的基础接口-ExecuteRateLimiter。

@FunctionalInterface
public interface ExecuteRateLimiter<P,R>{

    /**
     * 执行操作
     * @param param
     * @return
     */
    R execute(P param);
}

这个各类主要代表限流器的执行操作方法。

定义限流器工厂方法

接下来,我们定义一下限流器工厂方法类ExecuteRateLimiterFactory。主要目的作为我们限流器的创建限流器的功能。

@FunctionalInterface
public interface ExecuteRateLimiterFactory<P,R> {
    R create(P param);
}

主要目的作为创建限流器ExecuteRateLimiter接口,接下来我们会进行覆盖和实现改接口进行构建不同厂商的限流器服务实现类。


Guava厂商的限流器所需要的参数类 — GuavaRateLimiterParam

在此,我们主要去实现我们 的限流器的参数实现类:GuavaRateLimiterParam。

@Builder
@Data
public class GuavaRateLimiterParam {

    private int permitsPerSecond;

    private int warmupPeriod;
 
    private TimeUnit timeUnit;
}

主要去属于封装了对应的Guava限流器的参数属性:

  • permitsPerSecond: 返回的RateLimiter的速率,意味着每秒有多少个许可变成有效。
  • warmupPeriod: 在这段时间内RateLimiter会增加它的速率,在抵达它的稳定速率或者最大速率之前
  • timeUnit:参数warmupPeriod 的时间单位

Guava厂商的限流器工厂类 — GuavaExecuteRateLimiterFactory

首先,我们需要进行实现属于我们Guava厂商的限流器的工厂类,主要目的是去实现对应的Guava的限流器的核心类:RateLimiter,并且作为我们Spring容器的一个组件进行注册到容器中去。

@Component
public class GuavaExecuteRateLimiterFactory implements ExecuteRateLimiterFactory<GuavaRateLimiterParam,RateLimiter> {

    /**
     * 创建RateLimiter对象
     * @param param
     * @return
     */
    @Override
    public RateLimiter create(GuavaRateLimiterParam param) {
        return RateLimiter.create(param.getPermitsPerSecond(),param.getWarmupPeriod(),param.getTimeUnit());
    }
}

实现面向切面模式的限流器实现功能

  • 限流器注解
  • 限流器切面

限流器注解

限流器的注解,主要面向于限流器的功能的参数包装,方便开发者可以再注解上进行定义不同的参数选项,基本等价于我们的GuavaRateLimiterParam的属性参数。可见:

@java.lang.annotation.Target({ElementType.METHOD,ElementType.FIELD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
@Component
@Autowired(required = false)
public @interface GuavaExecuteRateLimiter {

    /**
     * 返回的RateLimiter的速率,意味着每秒有多少个许可变成有效。
     */
    int permitsPerSecond() default 500;

    /**
     * 在这段时间内RateLimiter会增加它的速率,在抵达它的稳定速率或者最大速率之前
     */
    int warmupPeriod() default 5;

    /**
     * 参数warmupPeriod 的时间单位
     */
    TimeUnit timeUnit() default TimeUnit.SECONDS;

}

限流器切面

主要针对于限流器的切面类进行控制处理-GuavaExecuteRateLimterAspect类。

@Slf4j
@Aspect
@Component
public class GuavaExecuteRateLimterAspect {
    @Pointcut("@annotation(com.hyts.assemble.ratelimiter.guava.anno.GuavaExecuteRateLimiter)")
    public void methodPointCut() {}


    @Autowired
    GuavaExecuteRateLimiterFactory executeRateLimiterFactory;


    ConcurrentHashMap<String, RateLimiter> rateLimiterConcurrentHashMap = new ConcurrentHashMap<>();



    Joiner joiner = Joiner.on("-").skipNulls();



    @Around("methodPointCut()")
    public Object doMethod(ProceedingJoinPoint proceedingJoinPoint){
        MethodSignature methodSignature = (MethodSignature)proceedingJoinPoint.getSignature();
        Method method = methodSignature.getMethod();
        GuavaExecuteRateLimiter guavaExecuteRateLimiter = method.getAnnotation(GuavaExecuteRateLimiter.class);
        GuavaRateLimiterParam guavaRateLimiterParam = GuavaRateLimiterParam.builder().
                permitsPerSecond(guavaExecuteRateLimiter.permitsPerSecond()).
                timeUnit(guavaExecuteRateLimiter.timeUnit()).
                warmupPeriod(guavaExecuteRateLimiter.warmupPeriod()).build();
        String key = joiner.join(guavaExecuteRateLimiter.permitsPerSecond(),
                guavaExecuteRateLimiter.timeUnit().toString()
                ,guavaExecuteRateLimiter.warmupPeriod());
        RateLimiter rateLimiter = rateLimiterConcurrentHashMap.
                computeIfAbsent(key,param-> executeRateLimiterFactory.create(guavaRateLimiterParam));
        try {
            double rateValue = rateLimiter.acquire();
            log.info("执行限流方法操作处理:当前qps:{} delay rate limiter value:{}",guavaExecuteRateLimiter.permitsPerSecond(),rateValue);
            return proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
        } catch (Throwable e) {
            log.error("执行限流控制方法失败!",e);
            return null;
        }
    }
}

主要用于通过AOP进行实时构建GuavaExecuteRateLimiterFactory进行构建和创建对应的RateLimiter对象,并且缓存到对应的容器里面进行构建。
进行执行限流操纵控制。

相关文章
|
存储 负载均衡 算法
zk基础—4.zk实现分布式功能
本文详细介绍了基于 ZooKeeper(ZK)实现分布式系统中的多种核心功能,包括数据发布订阅、负载均衡、分布式命名服务、Master-Worker 协调、分布式通信、Master 选举、分布式锁及分布式队列与屏障的实现。每部分均包含原理说明和具体代码示例,展示了 ZK 在分布式环境下的协调能力与应用场景。
|
运维 监控 Linux
WGCLOUD运维平台的分布式计划任务功能介绍
WGCLOUD是一款免费开源的运维监控平台,支持主机与服务器性能监控,具备实时告警和自愈功能。本文重点介绍其计划任务功能模块,可统一管理Linux和Windows主机的定时任务。相比手动配置crontab或Windows任务计划,WGCLOUD提供直观界面,通过添加cron表达式、执行指令或脚本并选择主机,即可轻松完成任务设置,大幅提升多主机任务管理效率。
|
安全 JavaScript 前端开发
HarmonyOS NEXT~HarmonyOS 语言仓颉:下一代分布式开发语言的技术解析与应用实践
HarmonyOS语言仓颉是华为专为HarmonyOS生态系统设计的新型编程语言,旨在解决分布式环境下的开发挑战。它以“编码创造”为理念,具备分布式原生、高性能与高效率、安全可靠三大核心特性。仓颉语言通过内置分布式能力简化跨设备开发,提供统一的编程模型和开发体验。文章从语言基础、关键特性、开发实践及未来展望四个方面剖析其技术优势,助力开发者掌握这一新兴工具,构建全场景分布式应用。
1177 35
|
消息中间件 缓存 算法
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
1569 0
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
469 5
|
运维 供应链 前端开发
中小医院云HIS系统源码,系统融合HIS与EMR功能,采用B/S架构与SaaS模式,快速交付并简化运维
这是一套专为中小医院和乡镇卫生院设计的云HIS系统源码,基于云端部署,采用B/S架构与SaaS模式,快速交付并简化运维。系统融合HIS与EMR功能,涵盖门诊挂号、预约管理、一体化电子病历、医生护士工作站、收费财务、药品进销存及统计分析等模块。技术栈包括前端Angular+Nginx,后端Java+Spring系列框架,数据库使用MySQL+MyCat。该系统实现患者管理、医嘱处理、费用结算、药品管控等核心业务全流程数字化,助力医疗机构提升效率和服务质量。
868 4
|
算法 前端开发 定位技术
地铁站内导航系统解决方案:技术架构与核心功能设计解析
本文旨在分享一套地铁站内导航系统技术方案,通过蓝牙Beacon技术与AI算法的结合,解决传统导航定位不准确、路径规划不合理等问题,提升乘客出行体验,同时为地铁运营商提供数据支持与增值服务。 如需获取校地铁站内智能导航系统方案文档可前往文章最下方获取,如有项目合作及技术交流欢迎私信我们哦~
1349 1
|
存储 智能硬件
CPU的定义与功能与架构
CPU(中央处理器)是计算机的核心部件,负责执行程序指令、控制数据传输和进行运算。它能处理算术与逻辑运算,并协调其他硬件协同工作。x86架构源于英特尔,适用于PC和服务器,采用复杂指令集;ARM架构则由Acorn等公司开发,广泛用于移动设备和嵌入式系统,采用精简指令集,功耗低且能效比高。
1818 5
|
网络协议 Java 应用服务中间件
框架源码私享笔记(01)Tomcat核心架构功能 | 配置详解
本文首先分享了《活出意义来》一书序言中的感悟,强调成功如同幸福,不是刻意追求就能得到,而是全心投入时的副产品。接着探讨了Tomcat的核心功能与架构解析,包括网络连接器(Connector)和Servlet容器(Container),并介绍了其处理HTTP请求的工作流程。文章还详细解释了Tomcat的server.xml配置文件,涵盖了从顶级容器Server到子组件Connector、Engine、Host、Context等的配置参数及作用,帮助读者理解Tomcat的内部机制和配置方法。
|
机器学习/深度学习 存储
DeepSeek进阶开发与应用4:DeepSeek中的分布式训练技术
随着深度学习模型和数据集规模的扩大,单机训练已无法满足需求,分布式训练技术应运而生。DeepSeek框架支持数据并行和模型并行两种模式,通过将计算任务分配到多个节点上并行执行,显著提高训练效率。本文介绍DeepSeek中的分布式训练技术,包括配置与启动方法,帮助用户轻松实现大规模模型训练。数据并行通过`MirroredStrategy`同步梯度,适用于大多数模型;模型并行则通过`ParameterServerStrategy`异步处理大模型。DeepSeek简化了分布式环境配置,支持单机多卡和多机多卡等场景。

热门文章

最新文章