Sentinel——限流

Sentinel是一种流量控制工具,本文详细介绍了Sentinel的限流概念和实现方式,如计数器、漏斗算法、令牌桶算法。通过SpringBoot集成Sentinel,展示了如何配置规则限制资源的请求频率,以及Sentinel控制台的安装、启动和资源规则配置。通过实例演示了配置QPS限流规则,并观察到限流效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 、 什么是Sentinel限流

限制请求的数量,限制某段时间内的请求总量对于超出的总量的请求,可以直接拒绝,也可以在请求的时候对请求分组,允许特殊请求进来,剩下的拒绝,也可以放入消息队列,削峰填谷。


限流的实现方式

  • 计数器(滑动窗口):维护一个counter,每个时间段清零,对时间段内的请求进行计数,计数前判断counter是否达到阙值,如果没有就加一,达到则拒绝
  • 漏斗算法:一个固定容量的桶,当桶为空的时候,不会漏出水滴,流入桶的水的速率是任意的,漏出水的速率是固定的,如果流入桶的水超出桶的容量,进行拒绝
    一般的实现方法是队列,队列模拟漏斗,空的时候不再出队,满的时候拒绝
  • 令牌桶算法:和漏斗算法很类似,不过除了一个队列以外,还加入了一个中间人,它会以一定的速率发放令牌(token)到桶内,队列中的的等待着只有拿到token才能通过漏斗限制了传输速率,而令牌桶在限制的同时,还允许突然的大流量,即:在大流量到来的时候,有足够空间的情况下(足够的队列和桶内有足够的令牌),就允许进入

 Sentinel代码示例效果

Sentinel的使用步骤大致可以分为三步:

  1. 引入依赖
  2. 定义资源
  3. 定义规则

1.引入依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.2</version>
</dependency>

2.定义资源

public static void main(String[] args) {
    // 配置规则.
    initFlowRules();
    while (true) {
        // 1.5.0 版本开始可以直接利用 try-with-resources 特性,自动 exit entry
        try (Entry entry = SphU.entry("HelloWorld")) {
            // 被保护的逻辑
            System.out.println
### 配置 Sentinel 网关进行流量限制 #### 启用 Sentinel 对网关的支持 为了使 Sentinel 正确工作于 API Gateway 上,需确保引入了 `Sentinel API Gateway Adapter Common` 模块。该模块提供了必要的组件来支持网关级别的限流功能[^2]。 对于基于 Spring Cloud Alibaba 的项目,在 pom.xml 文件中加入依赖: ```xml <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-apache-httpclient-adapter</artifactId> </dependency> <!-- 如果使用的是 Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> ``` #### 设置基础配置属性 在 application.yml 中添加如下配置以启用并调整基本行为: ```yaml spring: cloud: sentinel: filter: enabled: true # 开启过滤器,默认开启;如果看到URL资源,则应设为false gw-flow-rules: # 自定义网关流控规则的数据源路径(可选) source: classpath:/gateway-flow-rules.json ``` 注意当观察到 URL 资源而非预期的路由或API分组时,应当将 `filter.enabled` 设定为 `false` 来修正这一情况[^4]。 #### 创建自定义 API 分组 可以通过编码方式创建 ApiDefinition 实现更细粒度的控制。例如,假设希望把 `/api/v1/*` 下的所有请求视为同一个 API 分组来进行统一管理: ```java import com.alibaba.csp.sentinel.adapter.gateway.common.rule.ApiPredicateItem; import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayApiDefinitionManager; public void initCustomApis() { List<ApiPredicateItem> items = new ArrayList<>(); items.add(new SubPathMatchable().setPattern("/api/v1/**")); Set<String> apiNames = Collections.singleton("my_custom_api"); GatewayApiDefinitionManager.loadApiDefinitions(apiNames, items); } ``` 这段代码会注册一个新的名为 "my_custom_api" 的 API 分组,并将其映射至特定模式下的所有子路径上。 #### 定义网关限流规则 同样地,也可以编程化地设置 GatewayFlowRule 。这里给出一个简单的例子说明如何针对某个 Route 或者之前提到过的自定义 API 分组实施限流策略: ```java import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler; import org.springframework.context.annotation.Bean; import java.util.Collections; @Bean public BlockRequestHandler blockRequestHandler(){ return (serverWebExchange, throwable) -> serverWebExchange.getResponse() .writeWith(Mono.just( ServerHttpResponse.writeAndFlushWith(Flux.just( Mono.just(ResponseEntity.ok("{\"code\": \"429\", \"msg\":\"Too Many Requests\"}")))) )); } // 添加限流规则... List<GatewayFlowRule> rules = Arrays.asList( new GatewayFlowRule("some_route_id_or_api_group_name") .setCount(10)//每秒允许的最大访问次数 .setIntervalSec(1)); GatewayFlowRuleManager.loadRules(rules); ``` 上述片段展示了怎样设定最大 QPS (Queries Per Second)为 10 的速率限制,并指定了受影响的目标对象——这可以是一个具体的 route ID 或者前面所建立的那个叫做 “my_custom_api”的 API 分组名[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值