随笔 - 607,  文章 - 173,  评论 - 2,  阅读 - 21万

上节学习了《限流&熔断基本概念》,本节对常用微服务限流&熔断组件进行学习选型,通过对比分析,最终决定学习Sentinel组件。

若有不对之处,请予指正,不胜感激。

限流组件分析

常见的微服务限流组件有RateLimiter/Hystrix/Sentinel等,本节主要学习这三个限流组件。

RateLimiter

  • 简介

RateLimiter是Google开源工具包Guava提供的基于令牌锁算法实现的限流工具类。由于使用的是令牌锁算法,故需要设置令牌的上限。

  • 类图

可与IDE中,点击RateLimiter类,Ctrl+Alt+b,查看RateLimiter类图如下。

  • 源码解析

RateLimiter抽象类中方法如下:

 

方法说明:

1) create函数,用于创建 RateLimiter,源码中定义了两种创建RateLimiter的方法。参数permitsPerSecond表示每s允许的令牌数

    public static RateLimiter create(double permitsPerSecond) {
        return create(permitsPerSecond, RateLimiter.SleepingStopwatch.createFromSystemTimer());
    }
    public static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit) {
        Preconditions.checkArgument(warmupPeriod >= 0L, "warmupPeriod must not be negative: %s", warmupPeriod);
        return create(permitsPerSecond, warmupPeriod, unit, 3.0D, RateLimiter.SleepingStopwatch.createFromSystemTimer());
    }


2) acquire函数,用于获取令牌,源码中定义了两种获取令牌的方法。参数permits表示单次获取令牌的个数,默认为。

允许单次获取多个令牌,所以RateLimiter支持一定程度的突发流量。

如果剩余令牌数足够,则直接返回;如果不足,则需要等待permits*1/QPS 秒。

   @CanIgnoreReturnValue
    public double acquire() {
        return this.acquire(1);
    }

    @CanIgnoreReturnValue
    public double acquire(int permits) {
        long microsToWait = this.reserve(permits);
        this.stopwatch.sleepMicrosUninterruptibly(microsToWait);
        return 1.0D * (double)microsToWait / (double)TimeUnit.SECONDS.toMicros(1L);
    }

 


3)tryAcquire函数,用于尝试获取令牌。源码中定义个四种尝试获取令牌的方法。参数permits表示令牌个数,timeout表示超时时间,TimeUnit 表示超时时间参数。

public boolean tryAcquire(long timeout, TimeUnit unit) {
    return this.tryAcquire(1, timeout, unit);
}

public boolean tryAcquire(int permits) {
    return this.tryAcquire(permits, 0L, TimeUnit.MICROSECONDS);
}

public boolean tryAcquire() {
    return this.tryAcquire(1, 0L, TimeUnit.MICROSECONDS);
}

public boolean tryAcquire(int permits, long timeout, TimeUnit unit) {
    long timeoutMicros = Math.max(unit.toMicros(timeout), 0L);
    checkPermits(permits);
    long microsToWait;
    synchronized(this.mutex()) {
        long nowMicros = this.stopwatch.readMicros();
        if (!this.canAcquire(nowMicros, timeoutMicros)) {
            return false;
        }

        microsToWait = this.reserveAndGetWaitLength(permits, nowMicros);
    }

    this.stopwatch.sleepMicrosUninterruptibly(microsToWait);
    return true;
}

更深入源码学习,可查看SmoothBursty和SmoothWarmingUp 两个实现类。

时序图

以SmoothBursty类为例,时序图如下:

1)初始化限流器

 

2)请求令牌

3)尝试请求令牌

 

简单Demo

1) 添加Maven依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>x.x.x</version>
</dependency>


2) 测试类
场景,固定频率,执行某任务。

import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.RateLimiter;
import org.junit.jupiter.api.Test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;

public class RateLimiterTest {

    // 场景:按固定频率执行某个任务,每个任务间隔2s
    @Test
    void submitTasksTest() {
        // 每秒生成0.5个令牌,即生成一个令牌需要2s
        RateLimiter rateLimiter = RateLimiter.create(0.5);
        ListeningExecutorService executorService = MoreExecutors
                .listeningDecorator(Executors.newFixedThreadPool(5));
        for (int i = 0; i < 5; i++) {
            rateLimiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞
            executorService.submit(new MyTask("is " + i));
            System.out.println(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS").format(new Date()));
        }
        executorService.shutdown();
    }
}

class MyTask implements Runnable {
    String str;

    public MyTask(String str) {
        this.str = str;
    }

    @Override
    public void run() {
        System.out.println("Task2 call execute.." + str);
    }
}


运行结果:每个任务间隔2s。

Hystrix

简介

Hystrix是Spring Cloud框架中Netflix组件中的一个组件,提供了限流、熔断、降级等功能。

Github:

客户端配置依赖

pom.xml中新增依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>


活跃度

由于Netflix在github官网宣称不在开发新功能,推荐开发者只用其它仍然活跃的开源项目Resilience4J。

GitHub主页原文如下:(原文链接:

故Hystrix不作为学习重点。由于Hystrix推荐的resilience4目前国内使用较少,故也不作为学习重点,等后续再学习。

Sentinel

简介

Sentinel是阿里面向云原生开发的微服务流量控制、熔断降级的开源组件。

GitHub 源码: Sentinel

中文学习地址:quick-start

码云镜像:Wiki - Gitee.com

Sentinel历史

  • 2012 年,Sentinel 诞生,主要功能为入口流量控制。
  • 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
  • 2018 年,Sentinel 开源。

Sentinel优势

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

官网是这样介绍的

Sentinel 具有以下特征:

  • 丰富的应用场景:
    Sentinel承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀,即突发流量控制在系统容量可以承受的范围;消息削峰填谷;实时熔断下游不可用应用,等等。
  • 完备的监控功能:
    Sentinel同时提供最实时的监控功能,您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 简单易用的扩展点:
    Sentinel提供简单易用的扩展点,您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理,适配数据源等。

Sentinel工作原理

Sentinel 的主要工作机制如下:

  • 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
  • 根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便定义及改变规则。
  • Sentinel 提供实时的监控系统(DashBoard),方便快速了解目前系统的状态。

活跃度

综合对比

通过以上分析对比,考虑到长期演进以及云原生生态环境,最终选择Sentinel作为深入学习对象。

后续会开展Sentinel学习系列。



posted on   菜鸟乙  阅读(92)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2022-04-29 EffectiveJava 1创建和销毁对象 4通过私有构造器强化不可实例化的能力
2020-04-29 高效 告别996,开启java高效编程之门 3-12实战:常用终端操作之查找
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示

目录导航