SpringCloud Alibaba 核心组件解析:服务网关
技术栈:Spring Boot 3.2.0 + Spring Cloud Alibaba 2023.0.0.0-RC1 + Sentinel + Gateway + Nacos
6.1 是什么 — Sentinel 网关限流
Gateway 负责路由转发,Sentinel 负责流量控制。两者整合后,可以在网关层对进入微服务的流量进行统一限流和熔断,在请求到达微服务之前就拦截。
6.1.1 调用链路
客户端请求
│
▼
┌─────────────────────────────┐
│ Gateway (9528) │
│ ┌─────────────────────────┐ │
│ │ SentinelGatewayFilter │ │ ← 在这里拦截!超阈值直接拒绝
│ │ (网关层限流 QPS=2) │ │
│ └─────────┬───────────────┘ │
│ │ 通过限流 │
└────────────┼────────────────┘
▼
┌─────────────────────────────┐
│ Provider (9001) │
│ ┌─────────────────────────┐ │
│ │ @SentinelResource │ │ ← 服务层精细化限流
│ └─────────────────────────┘ │
└─────────────────────────────┘6.1.2 网关限流 vs 服务限流
| 层级 | 组件 | 粒度 | 场景 |
|---|---|---|---|
| 网关层 | GatewayFlowRule | 按路由或 API 分组 | 入口总流量控制 |
| 服务层 | @SentinelResource | 按接口/资源 | 精细化流量控制 |
6.2 为什么 — 网关层限流的优势
- 请求入口拦截:不让无效请求进入微服务层,节省资源
- 统一管理:所有路由规则集中在网关配置,不需要每个微服务各自配
- 安全防护:恶意刷量在网关层就被拦截
6.3 怎么做 — 完整实战
6.3.1 项目模块
| 模块 | 端口 | 说明 |
|---|---|---|
clooudalibaba-sentinel-gateway9528 | 9528 | Sentinel + Gateway |
cloudalibaba-provider-payment9001 | 9001 | 被代理的服务 |
6.3.2 步骤 ①:依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Sentinel 适配 Gateway 的桥接包 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>6.3.3 步骤 ②:配置
server:
port: 9528
spring:
application:
name: cloudalibaba-sentinel-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: pay_routh1
uri: http://localhost:9001 # 直接转发到 Provider
predicates:
- Path=/pay/**
sentinel:
log:
dir: D:/yangnan/Documents/SpringCloud/sentinel-log6.3.4 步骤 ③:核心配置类
// clooudalibaba-sentinel-gateway9528/.../config/GatewayConfiguration.java
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(
ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
// ① 注册 Sentinel 异常处理器(最高优先级)
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(
viewResolvers, serverCodecConfigurer);
}
// ② 注册 Sentinel 全局过滤器(Order=-1,低于上方的处理器,但高于其他过滤器)
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
// ③ 应用启动后初始化规则
@PostConstruct
public void doInit() {
initBlockHandler();
}
private void initBlockHandler() {
// 网关流控规则:对路由 pay_routh1 限制每秒最多 2 个请求
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("pay_routh1")
.setCount(2) // QPS 阈值
.setIntervalSec(1)); // 统计间隔 1 秒
GatewayRuleManager.loadRules(rules);
// 自定义限流响应(返回 JSON 而不是默认 HTML)
BlockRequestHandler handler = (exchange, t) -> {
Map<String, String> map = new HashMap<>();
map.put("errorCode",
HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
map.put("errorMessage",
"请求太过频繁,系统忙不过来,触发限流(sentinel+gateway整合Case)");
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(map));
};
GatewayCallbackManager.setBlockHandler(handler);
}
}配置解读:
| 组件 | 作用 |
|---|---|
SentinelGatewayBlockExceptionHandler | 处理限流时抛出的 BlockException |
SentinelGatewayFilter | 拦截每个请求,执行限流规则判断 |
GatewayFlowRule | 网关级流控规则,按 routeId 限流 |
BlockRequestHandler | 自定义被限流时返回的错误信息(JSON 格式) |
6.3.5 步骤 ④:验证
- 启动 Nacos → Gateway(9528) → Provider(9001)
- 快速连续访问
http://localhost:9528/pay/nacos/1 - QPS > 2 时返回自定义 JSON:
{
"errorCode": "Too Many Requests",
"errorMessage": "请求太过频繁,系统忙不过来,触发限流(sentinel+gateway整合Case)"
}6.4 深入原理 — 网关限流实现流程
请求到达 Gateway
│
▼
SentinelGatewayFilter.doFilter()
│
├→ 提取 routeId(如 "pay_routh1")
├→ 匹配 GatewayFlowRule(QPS=2)
├→ 判断是否超阈值
│
├→ 未超:chain.filter() → 转发到 Provider ✅
└→ 超了:throw BlockException → BlockRequestHandler → 返回 JSON ❌6.5 网关限流 vs 服务限流对比
| 维度 | 网关限流 | 服务限流 |
|---|---|---|
| 实现方式 | GatewayFlowRule + SentinelGatewayFilter | @SentinelResource |
| 配置位置 | 网关代码中硬编码或动态配置 | 控制台或注解 |
| 粒度 | 按路由/API 分组 | 按资源名/URL |
| 优势 | 统一入口,减少无效流量进入 | 精细化控制 |
| 劣势 | 无法感知服务内部逻辑 | 需要每个服务单独配置 |
6.6 面试题
Q1:网关层限流和服务层限流如何选择?
答:两者不是替代关系而是互补关系。网关层做粗粒度总流量控制(如每秒不超过 1000),服务层做细粒度接口控制(如秒杀接口单独限制)。双层防护更安全。
Q2:Sentinel 网关限流和 Resilience4J RequestRateLimiter 有什么区别?
答:Sentinel 需要独立部署 Dashboard,提供实时监控和规则热更新;Resilience4J RequestRateLimiter 是 Gateway 内置过滤器,配置简单但功能有限。
6.7 踩坑指南
| 坑 | 现象 | 原因 | 解决 |
|---|---|---|---|
| 🔴 过滤器优先级不对 | 限流不生效 | SentinelGatewayFilter 优先级低于其他过滤器 | 确保 @Order(-1) |
| 🔴 异常处理器不工作 | 限流后返回默认 HTML 错误页 | SentinelGatewayBlockExceptionHandler 未注册或优先级不够 | 确保 @Order(Ordered.HIGHEST_PRECEDENCE) |
| 🔴 sentinel-gateway-adapter 版本冲突 | NoClassDefFoundError | adapter 版本与 sentinel-core 不匹配 | 由 Spring Cloud Alibaba BOM 统一管理版本,不要手动指定 |
6.8 章节总结
| 要点 | 说明 |
|---|---|
| 三个关键 Bean | SentinelGatewayFilter(拦截请求)+ SentinelGatewayBlockExceptionHandler(处理异常)+ GatewayFlowRule(配置规则) |
| 规则配置 | GatewayFlowRule("routeId").setCount(N).setIntervalSec(S) |
| 自定义响应 | BlockRequestHandler 返回 JSON,替代默认 HTML |
| 双层防护 | 网关层粗粒度 + 服务层细粒度,组合使用 |
| @Order 很重要 | HIGHEST_PRECEDENCE 给异常处理器,-1 给过滤器 |
到此这篇关于SpringCloud Alibaba 核心组件解析:服务网关的文章就介绍到这了,更多相关SpringCloud Alibaba 服务网关内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解SpringMVC中的@RequestMapping注解
这篇文章主要介绍了SpringMVC中@RequestMapping注解,@RequestMapping注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上,需要的朋友可以参考下2023-07-07
Java的super关键字与instanceof运算符使用方法
这篇文章主要介绍了Java的super关键字与instanceof运算符使用方法,是Java入门学习中的基础知识,需要的朋友可以参考下2015-09-09
guava中Multimap、HashMultimap用法小结
这篇文章主要介绍了guava中Multimap、HashMultimap使用,Multimap它可以很简单的实现一些功能,LinkedHashMultimap实现类与HashMultimap类的实现方法一样,唯一的区别是LinkedHashMultimap保存了记录的插入顺序,本文就这些内容讲解的非常详细,需要的朋友参考下吧2022-05-05


最新评论