自定义限流器:轻松实现并发控,你真行!

本文介绍了自定义限流器在微服务中的应用,详细讲解了三层限流策略,以及如何实现基于Java的令牌桶算法限流器。通过AccessLimiter类和监控类的代码实现,阐述了限流器的工作原理和使用方法,最后推荐了Guava RateLimiter作为第三方限流解决方案。
摘要由CSDN通过智能技术生成

限流器介绍

限流器是一种用来控制请求速率的工具,它可以防止系统过载,并确保系统能够平稳运行。限流器的原理很简单,它通过限制一段时间内可以处理的请求数量来实现限流。

限流器在哪里

这里我们的限流器一般使用在第三层,也就是在某个微服务实例中使用。

三层限流

1层

nginx 限制ip的访问频率。

2层

Gateway中通过用户的唯一标识限制同一个用户的访问频率。

3层

微服务中限制业务访问的频率。

第三层直接应对的我们具体的业务,最接近开发者也最接近用户的功能,所以限流是相当重要。

限流器的应用场景

  • 限制资源消耗:例如,限制对数据库的查询频率,或者限制对文件系统的写入速度,以防止资源枯竭。
  • 防止过载:例如,限制对Web服务的请求频率,或者限制对消息队列的发送速度,以防止系统过载。
  • 平滑流量:例如,来平滑的对某个服务的请求流量,以防止服务出现抖动。
  • 实现令牌桶算法:令牌桶算法是一种经典的限流算法,可以很容易地实现令牌桶算法。
  • 实现漏桶算法:漏桶算法也是一种经典的限流算法,可以很容易地实现漏桶算法,一般可通过队列实现。

限流器通常使用方法

  1. 创建一个 限流器 对象。
  2. 调用对象的acquire()方法来获取一个令牌。
  3. 在获取到令牌之后,你就可以执行受限的操作了。
  4. 重复步骤2和步骤3,直到你的操作完成。

手撸限流器

这里我们使用java来自定义一个限流器

AccessLimiter 类

职责:
  • 限制对资源的并发访问的限制。
属性:
  • **name:**限流器的名称。
  • **rate:**每秒生成的令牌数。
  • **capacity:**令牌桶的最大容量。
  • **tokens:**当前令牌数。
  • **scheduler:**用于定时任务的线程池。
  • **warmupPeriod:**预热时间(秒)。
  • **warmupTimeUnit:**预热时间单位。
  • **isRunning:**限流器是否正在运行。
方法:
  • **constructor:**构造函数。
  • **getName:**获取限流器的名称。
  • **start:**开始运行限流器。
  • **refreshTokens:**刷新令牌。
  • **warmup:**令牌预热。
  • **tryAcquire:**尝试获取得到令牌,如果失败则阻塞直到成功或超时。
  • **allowed:**允许通过。
  • **throttled:**阻止通过。
  • **stop:**停止限流器。
代码:
/**
*包名称
*/
package com.qcmb.java.utils.access;


import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 访问限制器,工具类,此工具是根据令牌桶思想制作。
 * 说明:
 *  令牌桶的容量是有限的,
 *  令牌的生成速率是均匀的。
 *  并发请求的到达速率是均匀的。
 * 参数作用:
 *  capacity【令牌桶】的作用:
 *      在并发请求下限制并发请求的最大请求数量。
 *      例如:令牌生成速率提高到 500,这个限流器最多也只能同时处理 1000 个并发请求
 *  rate【令牌生成速率】作用:
 *      速率越低,令牌桶中令牌的生成速度就越慢。控制令牌桶中令牌的生成速度,那么也就间接的控制了并发请求数。
 * 注意事项:
 *  在实际应用中,令牌桶的容量和令牌生成速率需要根据实际情况进行调整。
 *  如果【令牌桶】的容量太小,那么这个限流器子多线程下就无法处理足够的并发请求。
 *  如果【令牌生成速率】太高,那么这个限流器就会开始丢弃令牌。
 *  因此,需要根据实际情况调整令牌桶的容量和令牌生成速率,以实现最佳效果。
 */
public class AccessLimiter {
    //监控器
    private final  IMonitor monitor;
    private final Object lock = new Object();
    /**
     * 限流器的名称
     */
    private final String name;
    private final int rate; // 每秒生成的令牌数
    private final int capacity; // 令牌桶的最大容量

    /**
     * 使用原子变量
     */
    private final AtomicInteger tokens; // 当前令牌数
    private final ScheduledExecutorService scheduler; // 用于定时任务的线程池
    private final long warmupPeriod; // 预热时间(秒)
    private final TimeUnit warmupTimeUnit; // 预热时间单位
    private final AtomicLong warmupTime = new AtomicLong(0); //预热的执行时间
    private vo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值