微服务网关是流量的统一入口,承担路由转发、负载均衡、认证鉴权、限流熔断等核心职责。Spring Cloud Gateway 作为 Spring 官方推荐的网关实现,配合阿里巴巴 Sentinel 的流量治理能力,可构建企业级的服务保护体系。
一、Spring Cloud Gateway 核心架构
1.1 请求处理流程
Client Request
│
▼
┌──────────────────────────────────────┐
│ Predicate(路由断言) │ ← 匹配路径、Header、时间等
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Pre Filter(前置过滤器) │ ← 认证、日志、灰度
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │ Proxy Request to Backend │
│ ▼ │
│ Post Filter(后置过滤器) │ ← 响应处理、埋点
└──────────────────────────────────────┘
1.2 路由与断言配置
spring:
cloud:
gateway:
routes:
# 订单服务路由
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
- Method=GET,POST
- Header=X-Api-Version, v[12] # Header 正则匹配
filters:
- StripPrefix=2 # 去掉 /api/order 前缀
- AddRequestHeader=X-Request-From, Gateway
- RequestRateLimiter=... # 限流
- CircuitBreaker=... # 熔断
# 支付服务路由(带重试)
- id: payment-service
uri: lb://payment-service
predicates:
- Path=/api/pay/**
filters:
- StripPrefix=2
- Retry=3 # 失败重试 3 次
- SetStatus=200 # 统一返回 200
1.3 自定义过滤器
@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthGatewayFilterFactory.Config> {
@Autowired
private JwtTokenProvider tokenProvider;
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String token = request.getHeaders().getFirst("Authorization");
if (!tokenProvider.validate(token)) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
// 透传用户信息到下游服务
ServerHttpRequest mutated = request.mutate()
.header("X-User-Id", tokenProvider.getUserId(token))
.header("X-User-Role", tokenProvider.getRole(token))
.build();
return chain.filter(exchange.mutate().request(mutated).build());
};
}
public static class Config {
// 配置参数
}
}
二、Sentinel 流量控制
2.1 核心概念
| 概念 | 说明 |
|---|---|
| 资源 | 被保护的方法、接口或代码块 |
| 规则 | 流量控制、熔断降级、系统保护、热点参数 |
| Slot Chain | 处理链:NodeSelector → ClusterBuilder → Log → Statistic → System → Authority → Flow → Degrade |
2.2 流控规则
@RestController
@RequestMapping("/api")
public class OrderController {
@GetMapping("/{id}")
@SentinelResource(
value = "getOrderById",
blockHandler = "getOrderBlockHandler",
fallback = "getOrderFallback"
)
public Order getOrder(@PathVariable Long id) {
return orderService.findById(id);
}
// 限流/降级时的响应
public Order getOrderBlockHandler(Long id, BlockException ex) {
log.warn("订单查询被限流: {}", id);
throw new RateLimitException("系统繁忙,请稍后重试");
}
// 业务异常时的降级
public Order getOrderFallback(Long id, Throwable ex) {
log.error("订单查询异常: {}", id, ex);
return Order.empty(id); // 返回降级数据
}
}
2.3 规则动态配置
@Configuration
public class SentinelConfig {
@PostConstruct
public void initRules() {
List<FlowRule> rules = new ArrayList<>();
// QPS 限流:每秒最多 1000 次
FlowRule qpsRule = new FlowRule("getOrderById")
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setCount(1000)
.setStrategy(RuleConstant.STRATEGY_DIRECT)
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)
.setWarmUpPeriodSec(10); // 预热 10 秒
// 线程数限流:最多 50 并发
FlowRule threadRule = new FlowRule("createOrder")
.setGrade(RuleConstant.FLOW_GRADE_THREAD)
.setCount(50);
rules.add(qpsRule);
rules.add(threadRule);
FlowRuleManager.loadRules(rules);
}
}
2.4 熔断降级规则
@PostConstruct
public void initDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
// 慢调用比例熔断
DegradeRule slowRule = new DegradeRule("getOrderById")
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
.setCount(500) // RT 超过 500ms 视为慢调用
.setTimeWindow(30) // 熔断时长 30 秒
.setSlowRatioThreshold(0.5) // 慢调用比例超过 50%
.setMinRequestAmount(10) // 最小请求数 10
.setStatIntervalMs(1000); // 统计时长 1 秒
// 异常比例熔断
DegradeRule errorRule = new DegradeRule("createOrder")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.5) // 异常比例超过 50%
.setTimeWindow(60) // 熔断时长 60 秒
.setMinRequestAmount(5)
.setStatIntervalMs(1000);
rules.add(slowRule);
rules.add(errorRule);
DegradeRuleManager.loadRules(rules);
}
三、Gateway 集成 Sentinel
3.1 网关流控
spring:
cloud:
gateway:
routes:
- id: order-route
uri: lb://order-service
predicates:
- Path=/order/**
filters:
- name: SentinelGatewayFilter
args:
flowConfig:
resource-mode: 0 # 0: route ID 模式, 1: 自定义 API 分组
@Configuration
public class GatewaySentinelConfig {
@PostConstruct
public void init() {
// 自定义 API 分组
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api = new ApiDefinition("order_api")
.setPredicateItems(new HashSet<>() {{
add(new ApiPathPredicateItem()
.setPattern("/order/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(api);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
// 网关流控规则
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("order_api")
.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
.setCount(100) // QPS 100
.setIntervalSec(1)
.setBurst(20) // 突发流量 20
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP));
GatewayRuleManager.loadRules(rules);
}
}
3.2 自定义限流响应
@Configuration
public class SentinelConfig {
@PostConstruct
public void init() {
BlockExceptionHandler handler = (exchange, ex) -> {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = JsonUtils.toJson(Map.of(
"code", 429,
"message", "当前访问人数过多,请稍后重试",
"timestamp", System.currentTimeMillis()
));
return response.writeWith(Mono.just(
response.bufferFactory().wrap(body.getBytes())
));
};
GatewayCallbackManager.setBlockHandler(handler);
}
}
四、高级限流策略
4.1 热点参数限流
@GetMapping("/hot")
@SentinelResource(
value = "hotParam",
blockHandler = "hotBlock"
)
public String hotParam(
@RequestParam("userId") @SentinelParam(idx = 0) String userId,
@RequestParam("skuId") @SentinelParam(idx = 1) String skuId
) {
return process(userId, skuId);
}
@PostConstruct
public void initParamRules() {
ParamFlowRule rule = new ParamFlowRule("hotParam")
.setParamIdx(0) // 对第 0 个参数限流
.setCount(100); // 默认 QPS 100
// 特定用户 ID 单独设置阈值
rule.setParamFlowItemList(List.of(
new ParamFlowItem().setObject("VIP_USER_001").setCount(1000),
new ParamFlowItem().setObject("BLACK_USER_001").setCount(0) // 黑名单
));
ParamFlowRuleManager.loadRules(List.of(rule));
}
4.2 系统自适应保护
@PostConstruct
public void initSystemRules() {
List<SystemRule> rules = new ArrayList<>();
rules.add(new SystemRule()
.setHighestSystemLoad(10.0) // 系统负载阈值
.setAvgRt(500) // 平均 RT 阈值(ms)
.setMaxThread(500) // 最大线程数
.setQps(5000) // 全局 QPS
.setHighestCpuUsage(0.7)); // CPU 使用率阈值
SystemRuleManager.loadRules(rules);
}
五、监控与管理
5.1 Sentinel 控制台
# 启动 Sentinel Dashboard
java -Dserver.port=8080 \
-Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard \
-jar sentinel-dashboard.jar
5.2 指标上报
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
port: 8719 # 应用与控制台通信端口
metric:
charset: UTF-8
fileSingleSize: 52428800 # 单个日志文件 50MB
fileTotalCount: 6 # 保留 6 个文件
datasource:
flow: # 规则持久化到 Nacos
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-flow-rules
ruleType: flow
六、最佳实践
6.1 网关限流设计
流量入口层级:
┌─────────────────┐
│ CDN / WAF │ ← 第一层:防 DDoS、CC 攻击
└────────┬────────┘
▼
┌─────────────────┐
│ Gateway Sentinel │ ← 第二层:API 级限流、鉴权
│ - 路由级 QPS │
│ - API 分组 │
└────────┬────────┘
▼
┌─────────────────┐
│ Service Sentinel │ ← 第三层:方法级限流、熔断
│ - 热点参数 │
│ - 慢调用熔断 │
└─────────────────┘
6.2 熔断策略参数推荐
| 场景 | 策略 | 阈值 | 熔断时长 | 恢复策略 |
|---|---|---|---|---|
| 核心接口 | 慢调用比例 | RT > 500ms | 30s | 半开试探 |
| 非核心接口 | 异常比例 | 错误率 > 50% | 60s | 半开试探 |
| 第三方调用 | 异常数 | 5 次/分钟 | 120s | 半开试探 |
七、总结
| 组件 | 职责 | 关键能力 |
|---|---|---|
| Spring Cloud Gateway | 统一入口 | 路由、转发、过滤、负载均衡 |
| Sentinel | 流量治理 | 限流、熔断、热点、系统保护 |
| 整合优势 | 全链路防护 | 网关层 + 服务层双重保护 |
网关层 Sentinal 适合粗粒度限流(API 级别),服务层 Sentinel 适合细粒度控制(方法级别)。两者结合,构建完整的微服务流量防护体系。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。