微服务篇之Sentinel限流熔断(二)— URL资源清洗

本文介绍了Sentinel在处理HTTP服务限流时,如何因REST风格API导致的资源统计不准确和资源数量过多的问题。通过实现UrlCleaner接口并重写clean方法,可以将/clean/{id}

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

Sentinel中HTTP服务的限流默认由Sentinel-Web-Servlet包中的CommonFilter来实现,从代码中可以看到,这个Filter会把每个不同的URL都作为不同的资源来处理。
在下面这段代码中,提供了一个携带{id}参数的REST风格API,对于每一个不同的{id},URL也都不一样,所以在默认情况下Sentinel会把所有的URL当做资源来进行流控。

package com.yuntai.gateway.config;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UrlCleanController {
    
    @GetMapping("/clean/{id}")
    public String clean(int id){
        return "Hello Clean";
    }
}

这会导致两个问题:
1、限流统计不准确,实际需求是控制clean方法总的QPS,结果统计的是每个URL的QPS;
2、导致Sentinel中资源数量过多,默认资源数量的阈值是6000,对于多出的资源规则将不会生效。

针对这个问题可以通过UrlCleaner接口来实现资源清洗,也就是对于/clean/{id}这个URL,我们可以统一归集到/clean/*资源下,具体配置代码如下,实现UrlCleaner接口,并重写clean方法即可。

package xxx;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

@Component
public class CustomUrlCleaner implements UrlCleaner {
    @Override
    public String clean(String originUrl) {
        if(StringUtils.isBlank(originUrl)){
            return originUrl;
        }
        if(originUrl.startsWith("/clean/")){
            return "/clean/*";
        }
        return originUrl;
    }
}

摘自鼓泡学院《Spring Cloud Alibaba微服务原理与实践》一书

### 使用 Sentinel 实现限流熔断的最佳实践 #### 1. 配置网关模块中的限流规则 当使用 Spring Cloud Gateway 和 Sentinel 结合时,建议在 Sentinel 控制台上针对网关模块设置具体的限流规则[^1]。这些规则可以通过控制台动态调整,适用于不同的业务场景。 #### 2. 使用 `@SentinelResource` 注解实现方法级别的限流熔断 对于 Java 方法层面的限流熔断,可以利用 `@SentinelResource` 注解完成配置[^2]。该注解支持多种参数,例如资源名称、限流阈值以及降级处理逻辑等。 以下是基于 `@SentinelResource` 的示例代码: ```java import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; public class Service { @SentinelResource(value = "exampleMethod", blockHandler = "handleBlock", fallback = "handleFallback") public String exampleMethod(String param) { if (param == null || param.isEmpty()) { throw new IllegalArgumentException("Parameter cannot be empty"); } return "Success: " + param; } // 处理限流异常 public String handleBlock(String param, BlockException exception) { return "Blocked by Sentinel: " + exception.getMessage(); } // 处理其他运行时异常 public String handleFallback(String param) { return "Fallback handler executed"; } } ``` 上述代码中: - `value`: 定义受保护的资源名。 - `blockHandler`: 当触发限流时调用的方法。 - `fallback`: 当发生其他异常时执行的回退方法。 #### 3. 熔断机制的状态管理 Sentinel 中的熔断器会在设定的时间窗口内统计请求的成功率或响应时间,并据此决定是否进入熔断状态。一旦达到预设条件,熔断器将切换到打开状态(Open)。经过指定的熔断时长后,熔断器会自动转换为半开状态(Half Open),并允许少量试探性请求通过。如果这些请求仍然失败或者响应超时,则重新进入熔断状态;反之则恢复至关闭状态(Closed)[^3]。 #### 4. 动手实验:快速入门 Sentinel 为了更好地理解 Sentinel 的工作原理及其实际效果,可以从官方文档提供的简单案例入手[^4]。具体步骤如下: - **Step 1**: 准备好实验所需的开发环境和服务端实例; - **Step 2**: 创建一个基础项目并将必要的依赖引入其中; - **Step 3**: 编写测试接口并通过模拟高并发流量验证其防护能力。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值