Spring Cloud Gateway 与 Sentinel 集成详解

摘要

本文深入探讨Spring Cloud Gateway与Sentinel流量控制框架的集成机制,包括流量控制、熔断降级、系统自适应保护等内容。通过详细的代码示例和架构分析,帮助开发者构建高可用的网关流量控制体系。

1. Sentinel 集成概述

1.1 Sentinel 简介

Sentinel是阿里巴巴开源的流量控制组件,提供流量控制、熔断降级、系统负载保护等能力,是保障微服务稳定性的核心组件。

1.2 Spring Cloud Gateway 与 Sentinel 集成优势

  • 流量控制:精确控制API流量,防止系统过载
  • 熔断降级:服务不可用时自动熔断,保障系统稳定
  • 实时监控:提供实时的流量和系统监控
  • 动态规则:支持运行时规则动态调整

2. Sentinel 依赖与配置

2.1 依赖配置

<dependencies>
    <!-- Sentinel 核心依赖 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    <!-- Sentinel Nacos 数据源依赖 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    
    <!-- Sentinel 网关适配器 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
    </dependency>
</dependencies>

2.2 配置文件设置

spring:
  cloud:
    sentinel:
      transport:
        dashboard: ${SENTINEL_DASHBOARD_HOST:localhost}:${SENTINEL_DASHBOARD_PORT:8080}
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: xxxx:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
        ds2:
          nacos:
            server-addr: xxxx:8848
            dataId: ${spring.application.name}-degrade
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: degrade
        ds3:
          nacos:
            server-addr: xxxx:8848
            dataId: ${spring.application.name}-system
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: system
        ds4:
          nacos:
            server-addr: xxxx:8848
            dataId: ${spring.application.name}-authority
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: authority

# Sentinel 配置
sentinel:
  filter:
    enabled: true
  log:
    dir: logs/csp
    switch-pid: true
  metrics:
    file:
      single-size: 1073741824  # 1GB

3. 流量控制规则配置

3.1 流量控制规则类型

Sentinel支持多种流量控制规则:

  • 流量控制规则(Flow Rule):控制资源的流量
  • 熔断降级规则(Degrade Rule):处理异常情况下的熔断
  • 系统规则(System Rule):基于系统指标的保护
  • 授权规则(Authority Rule):黑白名单控制

3.2 流量控制规则配置示例

[
  {
    "resource": "GET:/user/info",
    "count": 10,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "POST:/order/create",
    "count": 5,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "GET:/api/public/**",
    "count": 100,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

3.3 网关流控规则配置

[
  {
    "resource": "common_api",
    "count": 20,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "GET:/user/**",
    "count": 15,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

4. Sentinel 自定义配置

4.1 Sentinel 配置类

/**
 * Sentinel 配置类
 * 配置Sentinel相关参数和规则
 */
@Configuration
@EnableConfigurationProperties(SentinelProperties.class)
public class SentinelConfig {
    
    /**
     * 自定义Sentinel网关适配器
     */
    @Bean
    @Order(-1)
    public SentinelGatewayFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }
    
    /**
     * 自定义网关流控异常处理器
     */
    @Bean
    @Order(-2)
    public BlockRequestHandler sentinelGatewayBlockExceptionHandler() {
        return new GatewayBlockRequestHandler();
    }
    
    /**
     * 初始化Sentinel规则
     */
    @PostConstruct
    public void init() {
        // 初始化网关流控规则
        initGatewayFlowRules();
        
        // 初始化自定义异常处理器
        initCustomBlockHandler();
    }
    
    /**
     * 初始化网关流控规则
     */
    private void initGatewayFlowRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        
        // API级别流控规则
        rules.add(new GatewayFlowRule("GET:/user/**")
            .setCount(10)
            .setIntervalSec(1));
            
        rules.add(new GatewayFlowRule("POST:/order/**")
            .setCount(5)
            .setIntervalSec(1));
            
        rules.add(new GatewayFlowRule("common_api")
            .setResourceMode(GatewayRuleManager.RESOURCE_MODE_ROUTE_ID)
            .setCount(20)
            .setIntervalSec(1));
        
        GatewayRuleManager.loadRules(rules);
    }
    
    /**
     * 初始化自定义异常处理器
     */
    private void initCustomBlockHandler() {
        BlockRequestHandler defaultBlockHandler = (exchange, t) -> {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 429);
            result.put("message", "请求过于频繁,请稍后再试");
            result.put("timestamp", System.currentTimeMillis());
            
            return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(result));
        };
        
        GatewayCallbackManager.setBlockHandler(defaultBlockHandler);
    }
}

4.2 网关流控异常处理器

/**
 * 网关流控异常处理器
 * 处理网关流控触发时的异常响应
 */
@Component
public class GatewayBlockRequestHandler implements BlockRequestHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(GatewayBlockRequestHandler.class);
    
    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable ex) {
        logger.warn("网关流控触发: {}", ex.getMessage());
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", 429);
        response.put("message", "请求过于频繁,请稍后再试");
        response.put("timestamp", System.currentTimeMillis());
        response.put("requestId", UUID.randomUUID().toString());
        
        // 根据异常类型返回不同的错误信息
        if (ex instanceof FlowException) {
            response.put("error", "流量控制");
        } else if (ex instanceof DegradeException) {
            response.put("error", "熔断降级");
        } else if (ex instanceof ParamFlowException) {
            response.put("error", "热点参数限流");
        } else {
            response.put("error", "限流异常");
        }
        
        return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(response));
    }
}

5. 网关流控适配器

5.1 自定义网关流控适配器

/**
 * 自定义网关流控适配器
 * 适配Spring Cloud Gateway的流控需求
 */
@Component
public class SentinelGatewayFilter implements GlobalFilter, Ordered {
    
    private static final Logger logger = LoggerFactory.getLogger(SentinelGatewayFilter.class);
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        String method = request.getMethodValue();
        
        // 构建资源名称
        String resource = method + ":" + path;
        
        Entry entry = null;
        try {
            // 创建Sentinel入口
            entry = SphU.entry(resource, EntryType.IN);
            
            // 继续执行后续过滤器
            return chain.filter(exchange);
            
        } catch (BlockException ex) {
            // 流控被触发,返回限流响应
            return handleBlockException(exchange, ex);
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }
    
    /**
     * 处理流控异常
     */
    private Mono<Void> handleBlockException(ServerWebExchange exchange, BlockException ex) {
        logger.warn("请求被流控限制: path={}, method={}", 
            exchange.getRequest().getURI().getPath(),
            exchange.getRequest().getMethodValue());
        
        // 使用默认的流控处理器
        return GatewayCallbackManager.getBlockHandler()
            .handleRequest(exchange, ex);
    }
    
    @Override
    public int getOrder() {
        return -1000; // 高优先级,确保在其他过滤器之前执行
    }
}

5.2 网关流控规则管理

/**
 * 网关流控规则管理服务
 * 管理网关级别的流控规则
 */
@Service
@Slf4j
public class GatewayFlowRuleService {
    
    /**
     * 添加网关流控规则
     */
    public void addGatewayFlowRule(String resource, int count, int intervalSec) {
        Set<GatewayFlowRule> rules = new HashSet<>();
        
        GatewayFlowRule rule = new GatewayFlowRule(resource)
            .setCount(count)
            .setIntervalSec(intervalSec);
            
        rules.add(rule);
        
        try {
            GatewayRuleManager.loadRules(rules);
            log.info("添加网关流控规则: resource={}, count={}, intervalSec={}", 
                resource, count, intervalSec);
        } catch (Exception e) {
            log.error("添加网关流控规则失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 添加API级别的流控规则
     */
    public void addApiFlowRule(String path, String method, int count, int intervalSec) {
        String resource = method + ":" + path;
        addGatewayFlowRule(resource, count, intervalSec);
    }
    
    /**
     * 添加路由级别的流控规则
     */
    public void addRouteFlowRule(String routeId, int count, int intervalSec) {
        GatewayFlowRule rule = new GatewayFlowRule(routeId)
            .setResourceMode(GatewayRuleManager.RESOURCE_MODE_ROUTE_ID)
            .setCount(count)
            .setIntervalSec(intervalSec);
            
        Set<GatewayFlowRule> rules = new HashSet<>();
        rules.add(rule);
        
        try {
            GatewayRuleManager.loadRules(rules);
            log.info("添加路由流控规则: routeId={}, count={}, intervalSec={}", 
                routeId, count, intervalSec);
        } catch (Exception e) {
            log.error("添加路由流控规则失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 清除所有流控规则
     */
    public void clearAllRules() {
        try {
            GatewayRuleManager.loadRules(new HashSet<>());
            log.info("清除所有网关流控规则");
        } catch (Exception e) {
            log.error("清除网关流控规则失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 获取当前流控规则
     */
    public List<GatewayFlowRule> getCurrentRules() {
        return GatewayRuleManager.getRules();
    }
}

6. 熔断降级配置

6.1 熔断降级规则配置

[
  {
    "resource": "GET:/user/info",
    "grade": 0,
    "count": 50,
    "timeWindow": 10,
    "minRequestAmount": 5,
    "statIntervalMs": 1000,
    "slowRatioThreshold": 0.5
  },
  {
    "resource": "POST:/order/create",
    "grade": 0,
    "count": 50,
    "timeWindow": 30,
    "minRequestAmount": 10,
    "statIntervalMs": 2000,
    "slowRatioThreshold": 0.7
  }
]

6.2 自定义熔断降级处理器

/**
 * 自定义熔断降级处理器
 * 处理服务不可用时的降级逻辑
 */
@Component
public class CustomDegradeHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(CustomDegradeHandler.class);
    
    /**
     * 处理服务降级
     */
    public Mono<ServerResponse> handleDegrade(ServerWebExchange exchange, String resource) {
        logger.warn("服务降级触发: resource={}", resource);
        
        // 返回降级响应
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200);
        response.put("message", "服务暂时不可用,已启用降级策略");
        response.put("data", null);
        response.put("timestamp", System.currentTimeMillis());
        response.put("fallback", true);
        
        return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(response));
    }
    
    /**
     * 处理异常降级
     */
    public Mono<ServerResponse> handleExceptionDegrade(ServerWebExchange exchange, 
                                                     String resource, Throwable ex) {
        logger.error("异常降级: resource={}, error={}", resource, ex.getMessage(), ex);
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", 500);
        response.put("message", "服务异常,已启用降级策略");
        response.put("error", ex.getMessage());
        response.put("timestamp", System.currentTimeMillis());
        response.put("fallback", true);
        
        return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(response));
    }
}

7. 系统自适应保护

7.1 系统规则配置

[
  {
    "metricType": 0,
    "count": 1.0,
    "grade": 1
  },
  {
    "metricType": 1,
    "count": 0.7,
    "grade": 1
  },
  {
    "metricType": 2,
    "count": 10000,
    "grade": 1
  },
  {
    "metricType": 3,
    "count": 2000,
    "grade": 1
  },
  {
    "metricType": 4,
    "count": 20,
    "grade": 1
  }
]

7.2 系统保护配置

/**
 * 系统保护配置
 * 配置系统级别的保护规则
 */
@Configuration
public class SystemProtectionConfig {
    
    @PostConstruct
    public void initSystemRules() {
        List<SystemRule> rules = new ArrayList<>();
        
        // CPU使用率保护
        SystemRule cpuRule = new SystemRule();
        cpuRule.setHighestSystemLoad(1.0); // 最高系统负载
        rules.add(cpuRule);
        
        // 平均RT保护
        SystemRule rtRule = new SystemRule();
        rtRule.setAvgRt(2000); // 平均响应时间2秒
        rules.add(rtRule);
        
        // 并发数保护
        SystemRule threadRule = new SystemRule();
        threadRule.setMaxThread(2000); // 最大线程数
        rules.add(threadRule);
        
        // QPS保护
        SystemRule qpsRule = new SystemRule();
        qpsRule.setQps(1000); // 每秒最大请求数
        rules.add(qpsRule);
        
        // 设置系统规则
        SystemRuleManager.loadRules(rules);
    }
}

8. Sentinel 监控与可视化

8.1 Sentinel Dashboard 集成

/**
 * Sentinel 监控配置
 * 配置Sentinel监控相关参数
 */
@Configuration
public class SentinelMonitorConfig {
    
    @Bean
    @ConditionalOnClass(MeterRegistry.class)
    public SentinelMetricsEventListener sentinelMetricsEventListener(MeterRegistry meterRegistry) {
        return new SentinelMetricsEventListener(meterRegistry);
    }
    
    /**
     * Sentinel指标事件监听器
     */
    @Component
    public static class SentinelMetricsEventListener {
        
        private final MeterRegistry meterRegistry;
        private final Counter flowCounter;
        private final Counter degradeCounter;
        private final Timer responseTimer;
        
        public SentinelMetricsEventListener(MeterRegistry meterRegistry) {
            this.meterRegistry = meterRegistry;
            this.flowCounter = Counter.builder("sentinel.flow.block")
                .description("Sentinel流控拦截次数")
                .register(meterRegistry);
            this.degradeCounter = Counter.builder("sentinel.degrade.block")
                .description("Sentinel熔断拦截次数")
                .register(meterRegistry);
            this.responseTimer = Timer.builder("sentinel.response.duration")
                .description("Sentinel响应耗时")
                .register(meterRegistry);
        }
        
        @EventListener
        public void handleSentinelEvent(BlockExceptionEvent event) {
            BlockException exception = event.getException();
            String resource = event.getResource();
            
            if (exception instanceof FlowException) {
                flowCounter.increment(Tags.of("resource", resource));
            } else if (exception instanceof DegradeException) {
                degradeCounter.increment(Tags.of("resource", resource));
            }
        }
    }
}

8.2 自定义指标收集

/**
 * 自定义指标收集服务
 * 收集和上报Sentinel相关指标
 */
@Service
@Slf4j
public class CustomMetricsService {
    
    private final MeterRegistry meterRegistry;
    
    public CustomMetricsService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    /**
     * 记录流控指标
     */
    public void recordFlowMetrics(String resource, boolean blocked, long duration) {
        // 记录流控统计
        Counter.builder("gateway.flow.control")
            .tag("resource", resource)
            .tag("blocked", String.valueOf(blocked))
            .register(meterRegistry)
            .increment();
        
        // 记录响应时间
        Timer.builder("gateway.response.time")
            .tag("resource", resource)
            .tag("blocked", String.valueOf(blocked))
            .register(meterRegistry)
            .record(duration, TimeUnit.MILLISECONDS);
    }
    
    /**
     * 记录熔断指标
     */
    public void recordDegradeMetrics(String resource, boolean degraded) {
        Counter.builder("gateway.degrade.control")
            .tag("resource", resource)
            .tag("degraded", String.valueOf(degraded))
            .register(meterRegistry)
            .increment();
    }
    
    /**
     * 记录系统负载指标
     */
    public void recordSystemMetrics() {
        // 记录系统负载相关指标
        Gauge.builder("system.cpu.usage")
            .register(meterRegistry, () -> {
                // 获取CPU使用率
                return getCpuUsage();
            });
        
        Gauge.builder("system.memory.usage")
            .register(meterRegistry, () -> {
                // 获取内存使用率
                return getMemoryUsage();
            });
    }
    
    private double getCpuUsage() {
        // 获取CPU使用率的实现
        return 0.5; // 示例值
    }
    
    private double getMemoryUsage() {
        // 获取内存使用率的实现
        return 0.6; // 示例值
    }
}

9. Sentinel 集成架构

客户端请求

Spring Cloud Gateway

Sentinel网关适配器

资源定义与统计

规则检查

规则是否触发?

继续处理请求

流控/熔断处理

自定义异常处理器

返回限流响应

路由到后端服务

后端服务响应

返回响应

指标收集

监控面板

系统保护检查

系统是否过载?

系统保护措施

正常处理

10. 动态规则配置

10.1 规则管理控制器

/**
 * 规则管理控制器
 * 提供动态规则管理接口
 */
@RestController
@RequestMapping("/sentinel/rules")
public class SentinelRuleController {
    
    @Autowired
    private GatewayFlowRuleService gatewayFlowRuleService;
    
    /**
     * 添加流控规则
     */
    @PostMapping("/flow")
    public Result<String> addFlowRule(@RequestBody FlowRuleDto flowRuleDto) {
        FlowRule rule = new FlowRule()
            .setResource(flowRuleDto.getResource())
            .setCount(flowRuleDto.getCount())
            .setGrade(flowRuleDto.getGrade())
            .setLimitApp(flowRuleDto.getLimitApp());
        
        try {
            FlowRuleManager.loadRules(Arrays.asList(rule));
            return Result.success("添加流控规则成功", flowRuleDto.getResource());
        } catch (Exception e) {
            return Result.error("添加流控规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 添加网关流控规则
     */
    @PostMapping("/gateway")
    public Result<String> addGatewayRule(@RequestBody GatewayRuleDto gatewayRuleDto) {
        try {
            GatewayFlowRule rule = new GatewayFlowRule(gatewayRuleDto.getResource())
                .setCount(gatewayRuleDto.getCount())
                .setIntervalSec(gatewayRuleDto.getIntervalSec());
            
            Set<GatewayFlowRule> rules = new HashSet<>();
            rules.add(rule);
            
            GatewayRuleManager.loadRules(rules);
            
            return Result.success("添加网关流控规则成功", gatewayRuleDto.getResource());
        } catch (Exception e) {
            return Result.error("添加网关流控规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取当前流控规则
     */
    @GetMapping("/flow")
    public Result<List<FlowRule>> getFlowRules() {
        List<FlowRule> rules = FlowRuleManager.getRules();
        return Result.success(rules);
    }
    
    /**
     * 获取网关流控规则
     */
    @GetMapping("/gateway")
    public Result<List<GatewayFlowRule>> getGatewayRules() {
        List<GatewayFlowRule> rules = GatewayRuleManager.getRules();
        return Result.success(rules);
    }
    
    /**
     * 删除流控规则
     */
    @DeleteMapping("/flow/{resource}")
    public Result<String> deleteFlowRule(@PathVariable String resource) {
        try {
            List<FlowRule> currentRules = FlowRuleManager.getRules();
            currentRules.removeIf(rule -> rule.getResource().equals(resource));
            FlowRuleManager.loadRules(currentRules);
            return Result.success("删除流控规则成功", resource);
        } catch (Exception e) {
            return Result.error("删除流控规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 清空所有规则
     */
    @DeleteMapping("/clear")
    public Result<String> clearAllRules() {
        try {
            FlowRuleManager.loadRules(new ArrayList<>());
            GatewayRuleManager.loadRules(new HashSet<>());
            return Result.success("清空所有规则成功");
        } catch (Exception e) {
            return Result.error("清空规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 规则传输对象
     */
    @Data
    public static class FlowRuleDto {
        private String resource;
        private int count;
        private int grade = 1; // 0代表线程数,1代表QPS
        private String limitApp = "default";
        private int intervalSec = 1;
    }
    
    @Data
    public static class GatewayRuleDto {
        private String resource;
        private int count;
        private int intervalSec = 1;
    }
}

11. 规则持久化

11.1 Nacos 规则持久化

/**
 * Nacos规则持久化服务
 * 将Sentinel规则持久化到Nacos配置中心
 */
@Service
@Slf4j
public class NacosRulePersistenceService {
    
    private final ConfigService configService;
    
    public NacosRulePersistenceService(NacosConfigManager nacosConfigManager) {
        this.configService = nacosConfigManager.getConfigService();
    }
    
    /**
     * 保存流控规则到Nacos
     */
    public boolean saveFlowRulesToNacos(List<FlowRule> rules) {
        try {
            String dataId = "gateway-flow-rules";
            String group = "SENTINEL_GROUP";
            String content = JSON.toJSONString(rules);
            
            boolean result = configService.publishConfig(dataId, group, content);
            if (result) {
                log.info("流控规则已保存到Nacos: {}", dataId);
            }
            return result;
        } catch (Exception e) {
            log.error("保存流控规则到Nacos失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 从Nacos加载流控规则
     */
    public List<FlowRule> loadFlowRulesFromNacos() {
        try {
            String dataId = "gateway-flow-rules";
            String group = "SENTINEL_GROUP";
            
            String content = configService.getConfig(dataId, group, 5000);
            if (StringUtils.hasText(content)) {
                return JSON.parseArray(content, FlowRule.class);
            }
        } catch (Exception e) {
            log.error("从Nacos加载流控规则失败: {}", e.getMessage(), e);
        }
        return new ArrayList<>();
    }
    
    /**
     * 保存网关流控规则到Nacos
     */
    public boolean saveGatewayRulesToNacos(Set<GatewayFlowRule> rules) {
        try {
            String dataId = "gateway-rules";
            String group = "SENTINEL_GROUP";
            String content = JSON.toJSONString(rules);
            
            boolean result = configService.publishConfig(dataId, group, content);
            if (result) {
                log.info("网关流控规则已保存到Nacos: {}", dataId);
            }
            return result;
        } catch (Exception e) {
            log.error("保存网关流控规则到Nacos失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 从Nacos加载网关流控规则
     */
    public Set<GatewayFlowRule> loadGatewayRulesFromNacos() {
        try {
            String dataId = "gateway-rules";
            String group = "SENTINEL_GROUP";
            
            String content = configService.getConfig(dataId, group, 5000);
            if (StringUtils.hasText(content)) {
                return new HashSet<>(JSON.parseArray(content, GatewayFlowRule.class));
            }
        } catch (Exception e) {
            log.error("从Nacos加载网关流控规则失败: {}", e.getMessage(), e);
        }
        return new HashSet<>();
    }
}

12. 性能优化

12.1 Sentinel 性能优化配置

/**
 * Sentinel 性能优化配置
 * 优化Sentinel相关性能参数
 */
@Configuration
public class SentinelPerformanceConfig {
    
    @PostConstruct
    public void optimizeSentinelConfig() {
        // 设置统计窗口大小
        InitExecutor.doInit();
        
        // 优化统计参数
        Options.setWarmUpPeriodSec(10); // 预热时间
        Options.setColdFactor(3); // 冷启动因子
        Options.setMaxOQPS(20000); // 最大QPS
        
        // 优化滑动窗口参数
        SpiLoader.loadExtensionClass();
    }
    
    /**
     * 自定义Sentinel线程池
     */
    @Bean
    @ConditionalOnMissingBean
    public ThreadPoolTaskExecutor sentinelTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(4);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("sentinel-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

13. 集成测试

13.1 Sentinel 集成测试

@SpringBootTest
@AutoConfigureTestDatabase
@TestPropertySource(properties = {
    "spring.cloud.sentinel.transport.dashboard=localhost:8080",
    "spring.cloud.sentinel.eager=true"
})
public class SentinelIntegrationTest {
    
    @Autowired
    private WebTestClient webTestClient;
    
    @Autowired
    private GatewayFlowRuleService gatewayFlowRuleService;
    
    @Test
    public void testFlowControl() {
        // 添加流控规则:每秒最多1个请求
        gatewayFlowRuleService.addApiFlowRule("/test/flow", "GET", 1, 1);
        
        // 第一个请求应该成功
        webTestClient.get()
            .uri("/test/flow")
            .exchange()
            .expectStatus().isOk();
        
        // 第二个请求应该被限流
        webTestClient.get()
            .uri("/test/flow")
            .exchange()
            .expectStatus().isEqualTo(HttpStatus.TOO_MANY_REQUESTS);
    }
    
    @Test
    public void testGatewayFlowControl() {
        // 添加网关流控规则
        gatewayFlowRuleService.addRouteFlowRule("test-route", 2, 1);
        
        // 测试网关流控
        IntStream.range(0, 5)
            .forEach(i -> {
                webTestClient.get()
                    .uri("/test/gateway")
                    .exchange()
                    .expectStatus()
                    .value(status -> assertThat(status).isIn(
                        HttpStatus.OK.value(),
                        HttpStatus.TOO_MANY_REQUESTS.value()
                    ));
            });
    }
    
    @Test
    public void testRuleManagement() {
        // 测试规则管理接口
        FlowRuleDto ruleDto = new FlowRuleDto();
        ruleDto.setResource("test-resource");
        ruleDto.setCount(5);
        
        webTestClient.post()
            .uri("/sentinel/rules/flow")
            .body(Mono.just(ruleDto), FlowRuleDto.class)
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            .jsonPath("$.code").isEqualTo(200);
    }
}

14. 最佳实践与建议

14.1 Sentinel 集成最佳实践

  1. 规则分级:按API重要性设置不同级别的流控规则
  2. 监控告警:建立流控触发的监控和告警机制
  3. 降级策略:制定合理的服务降级策略
  4. 配置管理:使用配置中心管理流控规则

14.2 性能优化建议

  1. 规则缓存:缓存常用流控规则
  2. 异步处理:流控检查采用异步方式
  3. 连接池优化:合理配置Sentinel连接池

15. 配置示例

15.1 完整配置文件

# Sentinel配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: ${SENTINEL_DASHBOARD:localhost:8080}
        port: 8719
        client-ip: ${SERVER_IP:127.0.0.1}
        heartbeat-interval-ms: 10000
      datasource:
        # 流控规则数据源
        flow:
          nacos:
            server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
            dataId: ${spring.application.name}-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            rule-type: flow
        # 熔断规则数据源
        degrade:
          nacos:
            server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
            dataId: ${spring.application.name}-degrade-rules
            groupId: SENTINEL_GROUP
            data-type: json
            rule-type: degrade
        # 系统规则数据源
        system:
          nacos:
            server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
            dataId: ${spring.application.name}-system-rules
            groupId: SENTINEL_GROUP
            data-type: json
            rule-type: system
        # 网关流控规则数据源
        gateway:
          nacos:
            server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
            dataId: ${spring.application.name}-gateway-rules
            groupId: SENTINEL_GROUP
            data-type: json
            rule-type: gateway_flow

# Sentinel相关配置
sentinel:
  filter:
    enabled: true
    order: -2000
  log:
    dir: logs/csp
    switch-pid: true
  metrics:
    file:
      single-size: 1073741824  # 1GB
      total-size: 10737418240  # 10GB

# 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  metrics:
    export:
      prometheus:
        enabled: true

16. 总结

Spring Cloud Gateway与Sentinel的集成提供了强大的流量控制和系统保护能力。通过合理的配置和实现,可以构建高可用、高稳定的网关系统。在实际应用中,需要根据业务特点设置合适的流控规则,并建立完善的监控体系。

17. 参考资料

  1. Sentinel官方文档
  2. Spring Cloud Alibaba Sentinel文档
  3. 流量控制最佳实践指南
  4. 微服务架构中的熔断降级模式

作者信息:本文详细介绍了Spring Cloud Gateway与Sentinel的集成,适合有一定微服务开发经验的开发者阅读。

注意事项:在生产环境中使用Sentinel时,需要根据实际业务流量调整流控参数。

扩展阅读:如需深入了解Sentinel高级特性,请参考Sentinel官方文档。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CarlowZJ

我的文章对你有用的话,可以支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值