摘要
本文深入探讨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 集成架构
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 集成最佳实践
- 规则分级:按API重要性设置不同级别的流控规则
- 监控告警:建立流控触发的监控和告警机制
- 降级策略:制定合理的服务降级策略
- 配置管理:使用配置中心管理流控规则
14.2 性能优化建议
- 规则缓存:缓存常用流控规则
- 异步处理:流控检查采用异步方式
- 连接池优化:合理配置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. 参考资料
- Sentinel官方文档
- Spring Cloud Alibaba Sentinel文档
- 流量控制最佳实践指南
- 微服务架构中的熔断降级模式
作者信息:本文详细介绍了Spring Cloud Gateway与Sentinel的集成,适合有一定微服务开发经验的开发者阅读。
注意事项:在生产环境中使用Sentinel时,需要根据实际业务流量调整流控参数。
扩展阅读:如需深入了解Sentinel高级特性,请参考Sentinel官方文档。
1142

被折叠的 条评论
为什么被折叠?



