Sentinel 整合 Spring Cloud + Gateway + 控制台Nacos持久化

项目版本

Spring Boot版本:2.2.9.RELEASE
Spring Cloud版本:Hoxton.SR7
Spring Cloud Alibaba版本:2.2.1.RELEASE

官方doc

所有功能文档概况
官方文档

介绍

本文分为以下几部分:

  • 普通服务集成
  • 控制台整合Nacos 自己Github重新封装地址
  • 网关集成(spring cloud gateway)
  • 控制台启动、参数和指定Nacos地址+namespace等

Nacos持久化最终效果图如下:

image.png

普通服务

普通服务效果图

注:Sentinel兼容Hystrix的FallbackFactory

从 Hystrix 迁移到 Sentinel方案(官方)

  • https://github.com/alibaba/Sentinel/wiki/Guideline:-%E4%BB%8E-Hystrix-%E8%BF%81%E7%A7%BB%E5%88%B0-Sentinel

Sentinel 与 Hystrix 的对比(官方)

  • https://github.com/alibaba/Sentinel/wiki/Sentinel-%E4%B8%8E-Hystrix-%E7%9A%84%E5%AF%B9%E6%AF%94
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class NacosProviderClientFallback implements FallbackFactory<NacosProviderClient> {

    @Override
    public NacosProviderClient create(Throwable throwable) {
        return new NacosProviderClient() {
            @Override
            public String abc(String name, int age) {
                log.error("用 nacos-provider abc 方法失败, 异常信息={}", throwable.getMessage());
                //throw new RuntimeException("abc:" + throwable.getMessage());
                //这里直接返回BusinessException(),因为
                throw new RuntimeException("aaaaaaadssssssssssss");
//                return throwable.getClass().getName() + " : " + throwable.getMessage();
            }

            @Override
            public String getEcho(String string) {
                log.error("用 nacos-provider getEcho 方法失败", throwable);
                throw new RuntimeException("getEcho:" + throwable.getMessage());
            }
        };
    }
}
基础包

基础包大概截图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4jyKDPvL-1603193351351)(https://upload-images.jianshu.io/upload_images/23703439-9c0ba26f2dac32e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

引入以下两个包,一个是sentinel核心组件,一个是整合nacos实现持久化功能组件(无关顺序

        <!-- alibaba Sentinel组件 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <!-- alibaba Sentinel整合nacos组件 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

添加自定义异常处理(不加会返回默认的错误信息Blocked by Sentinel: XXXX

注: 网上方案实现 UrlBlockHandler 接口的版本已经比较老了,新版本已经没有UrlBlockHandler 接口

/**
 * 没有配资源,默认Block异常处理(只能是Block异常)
 */
@Slf4j
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        httpServletResponse.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value());
        if (e instanceof FlowException) {
            log.error("FlowException 普通服务限流,资源信息:" + JSON.toJSONString(e.getRule()));
            httpServletResponse.setStatus(org.springframework.http.HttpStatus.TOO_MANY_REQUESTS.value());
            ResponseUtil.responseFailed(objectMapper, httpServletResponse, 1000, "API interface limited flow.");
        } else if (e instanceof DegradeException) {
            log.error("DegradeException 普通服务降级,资源信息:" + JSON.toJSONString(e.getRule()));
            ResponseUtil.responseFailed(objectMapper, httpServletResponse, 1001, "API interface has been degraded.");
        } else if (e instanceof ParamFlowException) {
            ParamFlowException ex = (ParamFlowException) e;
            log.error("ParamFlowException 参数热点限流,资源名={},参数={},资源信息={}", ex.getResourceName(), ex.getLimitParam(), JSON.toJSONString(ex.getRule()));
            ResponseUtil.responseFailed(objectMapper, httpServletResponse, 1002, "API interface limited flow by params.");
        } else if (e instanceof AuthorityException) {
            log.error("AuthorityException 授权规则,资源信息:" + JSON.toJSONString(e.getRule()));
            ResponseUtil.responseFailed(objectMapper, httpServletResponse, 1003, "API interface limited by autho
<think>好的,我需要帮助用户在Spring Cloud Gateway中集成Sentinel以实现流量控制和熔断保护。首先,我得回忆一下Spring Cloud GatewaySentinel的基本知识。Spring Cloud GatewaySpring Cloud提供的API网关,用于路由、监控、弹性等。而Sentinel是阿里巴巴开源的流量控制组件,支持熔断降级、系统保护等功能。 用户的问题是要在Gateway中集成Sentinel,进行限流和熔断。我需要考虑如何添加依赖、配置规则以及编写代码示例。首先,应该引入相关的依赖,比如Spring Cloud Alibaba SentinelSentinelGateway适配器。然后,配置Sentinel的相关属性,比如dashboard地址。接下来,可能需要自定义一些异常处理,因为默认的限流返回信息可能不符合需求。 然后,需要设置流量控制规则,比如QPS的限制,或者熔断策略,比如慢调用比例、异常比例等。Sentinel提供了GatewayRuleManager来管理规则。另外,可能需要通过代码或Dashboard来动态配置这些规则,确保网关能够根据实际情况调整策略。 另外,还需要考虑资源名称的定义,比如使用路由ID作为资源名,或者自定义API分组。同时,熔断后的降级处理也很重要,比如返回友好的错误信息,或者重定向到备用服务。 还要注意Spring Cloud Gateway的版本和Spring Cloud Alibaba版本的兼容性,避免出现依赖冲突。另外,Sentinel Dashboard的使用可以帮助用户更直观地查看和管理规则,所以需要指导用户如何启动和配置Dashboard。 最后,测试整个配置是否生效,比如通过发送请求触发限流或熔断,观察返回结果是否符合预期。如果有问题,可能需要检查日志或调整规则参数。 现在需要将这些步骤结构化,确保用户能够一步步操作。同时,生成相关问题,比如性能优化、自定义规则、与Zuul的对比等,帮助用户进一步探索。</think>### 在Spring Cloud Gateway中集成Sentinel实现流量控制与熔断保护 以下是集成步骤及最佳实践: #### 1. 添加依赖 在`pom.xml`中引入关键依赖: ```xml <!-- Spring Cloud Alibaba Sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- Sentinel Gateway适配器 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> ``` 需注意版本兼容性,推荐使用Spring Cloud 2021.0.5 + Spring Cloud Alibaba 2021.0.5.0[^2]。 #### 2. 配置Sentinel Dashboard ```yaml spring: cloud: sentinel: transport: dashboard: localhost:8080 # Sentinel控制台地址 eager: true # 立即初始化 scg: filter: enabled: true # 启用网关过滤 ``` #### 3. 定义流量控制规则 ```java @PostConstruct public void initRules() { // 定义网关流控规则 List<GatewayFlowRule> rules = new ArrayList<>(); rules.add(new GatewayFlowRule("product_route") .setCount(100) // 阈值 .setIntervalSec(1) // 统计窗口 .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)); GatewayRuleManager.loadRules(rules); } ``` 资源命名建议使用路由ID或自定义API分组。 #### 4. 配置熔断规则 ```java List<DegradeRule> degradeRules = new ArrayList<>(); degradeRules.add(new DegradeRule("payment_service") .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) // 异常比例模式 .setCount(0.5) // 阈值50% .setTimeWindow(10) // 熔断时长(s) .setMinRequestAmount(5)); // 最小请求数 DegradeRuleManager.loadRules(degradeRules); ``` #### 5. 自定义异常处理 ```java @Configuration public class GatewayConfig { @Bean @Order(-1) public SentinelGatewayBlockExceptionHandler sentinelBlockHandler() { return new SentinelGatewayBlockExceptionHandler( (exchange, ex) -> ServerResponse.ok() .contentType(MediaType.APPLICATION_JSON) .bodyValue(Map.of("code", 429, "msg", "请求过于频繁")) ); } } ``` #### 最佳实践建议 1. **动态规则配置**:通过Nacos等配置中心实现规则持久化 2. **分级保护**: - API维度:`/product/**` QPS=500 - 服务维度:订单服务总QPS=2000 3. **熔断策略组合**: - 慢调用比例(响应时间>1s)触发熔断 - 异常数阈值双重保护 4. **实时监控**:集成Prometheus+Grafana实现可视化监控
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值