SpringCloud 网关与熔断:Gateway + Sentinel 快速入门

🎯 本文适合人群 :SpringCloud 初学者、微服务开发者

⏱️ 阅读时长 :25 分钟

📌 你将收获:掌握 Gateway 网关配置、Sentinel 熔断降级、流量控制


📖 目录

  • [一、Gateway 网关快速入门](#一、Gateway 网关快速入门)
  • [二、Gateway 路由与过滤器](#二、Gateway 路由与过滤器)
  • [三、Sentinel 熔断降级](#三、Sentinel 熔断降级)
  • [四、Sentinel 流量控制](#四、Sentinel 流量控制)
  • [五、Gateway + Sentinel 整合](#五、Gateway + Sentinel 整合)
  • 六、常见面试题

一、Gateway 网关快速入门

1.1 为什么需要网关?

没有网关的问题

复制代码
❌ 客户端需要知道所有服务地址
❌ 跨域(CORS)问题
❌ 每个服务都要写鉴权代码
❌ 限流、日志分散

使用网关

复制代码
客户端 → Gateway(统一入口)→ 各个微服务

✅ 统一入口
✅ 统一鉴权、限流
✅ 动态路由
✅ 协议转换

1.2 Gateway 核心概念

概念 说明 示例
Route(路由) 请求路径 → 目标服务 /user/**user-service
Predicate(断言) 匹配条件 Path=/user/**
Filter(过滤器) 请求前后执行逻辑 鉴权、日志、限流

1.3 快速搭建 Gateway

步骤 1:依赖配置
xml 复制代码
<!-- pom.xml -->
<dependencies>
    <!-- Gateway -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
    <!-- Nacos 服务发现 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
    <!-- LoadBalancer -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
</dependencies>

注意 :Gateway 不要引入 spring-boot-starter-web,会冲突!

步骤 2:配置文件
yaml 复制代码
# application.yml
server:
  port: 9000

spring:
  application:
    name: gateway-service
  
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    
    gateway:
      routes:
        # 用户服务路由
        - id: user-route
          uri: lb://user-service  # lb = LoadBalancer
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix=1  # 去掉 /user 前缀
        
        # 订单服务路由
        - id: order-route
          uri: lb://order-service
          predicates:
            - Path=/order/**
          filters:
            - StripPrefix=1
步骤 3:启动类
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
步骤 4:测试
bash 复制代码
# 通过网关访问用户服务
curl http://localhost:9000/user/1001

# 实际转发到:http://user-service/1001

二、Gateway 路由与过滤器

2.1 Predicate(断言)常用类型

断言 说明 示例
Path 路径匹配 Path=/user/**
Method 请求方法 Method=GET,POST
Header 请求头匹配 Header=X-Token, .*
Query 查询参数 Query=version, v2
Host 主机匹配 Host=**.example.com

组合使用

yaml 复制代码
predicates:
  - Path=/api/**
  - Method=GET,POST
  - Header=X-Token, .*

2.2 Filter(过滤器)常用类型

过滤器 作用 示例
StripPrefix 去掉路径前缀 StripPrefix=1
AddRequestHeader 添加请求头 AddRequestHeader=X-Gateway, Gateway
AddResponseHeader 添加响应头 AddResponseHeader=X-Time, 100ms
RewritePath 重写路径 RewritePath=/red/(.*), /$\{segment}

2.3 自定义全局过滤器(鉴权)

java 复制代码
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // ① 获取请求
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        
        // ② 白名单:登录接口不需要鉴权
        if (path.equals("/user/login")) {
            return chain.filter(exchange);
        }
        
        // ③ 获取 Token
        String token = request.getHeaders().getFirst("Authorization");
        
        // ④ 验证 Token
        if (token == null || !token.startsWith("Bearer ")) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        
        // ⑤ Token 合法,放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;  // 优先级高
    }
}

三、Sentinel 熔断降级

3.1 什么是熔断降级?

问题场景:雪崩效应

复制代码
库存服务挂了:
用户请求 → 订单服务 → 库存服务(超时)
         ↓
      请求堆积 → 订单服务崩溃 → 系统瘫痪 ❌

解决方案:熔断器

复制代码
使用 Sentinel:
订单服务 → 检测到库存服务异常 → 熔断器打开
         → 快速失败 → 返回降级响应 ✅

3.2 Sentinel 快速入门

步骤 1:添加依赖
xml 复制代码
<!-- Sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
步骤 2:配置文件
yaml 复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080  # Sentinel 控制台
        port: 8719
步骤 3:定义资源
java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{id}")
    @SentinelResource(
        value = "getUserById",  // 资源名
        blockHandler = "handleBlock",  // 限流/熔断降级方法
        fallback = "handleFallback"  // 异常降级方法
    )
    public User getUserById(@PathVariable Long id) {
        if (id < 0) {
            throw new IllegalArgumentException("ID 不合法");
        }
        return new User(id, "用户" + id, 25, "user@example.com");
    }

    // 限流/熔断降级方法
    public User handleBlock(Long id, BlockException ex) {
        return new User(id, "系统繁忙", 0, "");
    }

    // 异常降级方法
    public User handleFallback(Long id, Throwable ex) {
        return new User(id, "服务异常", 0, "");
    }
}

3.3 熔断规则配置

java 复制代码
@Configuration
public class SentinelConfig {

    @PostConstruct
    public void initRules() {
        List<DegradeRule> rules = new ArrayList<>();
        
        // 异常比例熔断
        DegradeRule rule = new DegradeRule("getUserById");
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
        rule.setCount(0.5);  // 异常比例 50%
        rule.setTimeWindow(10);  // 熔断时长 10 秒
        rule.setMinRequestAmount(5);  // 最小请求数
        
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

3.4 熔断器状态机

复制代码
┌──────────┐
│  关闭    │ → 正常请求
└────┬─────┘
     │ 异常率 > 50%
     ↓
┌──────────┐
│  开启    │ → 拒绝所有请求
└────┬─────┘
     │ 等待 10 秒
     ↓
┌──────────┐
│  半开    │ → 尝试一次请求
└────┬─────┘
     ├─→ 成功 → 关闭
     └─→ 失败 → 开启

四、Sentinel 流量控制

4.1 限流规则

策略 说明 示例
QPS 每秒请求数 QPS ≤ 100
并发线程数 同时处理的请求数 并发 ≤ 10

流控效果

效果 说明
快速失败 超过阈值直接拒绝(默认)
Warm Up 预热,逐渐增加流量
排队等待 匀速排队,削峰填谷

4.2 限流规则配置

java 复制代码
@PostConstruct
public void initFlowRules() {
    List<FlowRule> rules = new ArrayList<>();
    
    // QPS 限流
    FlowRule rule = new FlowRule("getUserById");
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setCount(10);  // QPS = 10
    
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

4.3 Sentinel 控制台

下载启动

bash 复制代码
# 下载
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar

# 启动
java -jar sentinel-dashboard-1.8.6.jar

# 访问:http://localhost:8080
# 账号/密码:sentinel / sentinel

控制台功能

  • ✅ 实时监控(QPS、响应时间)
  • ✅ 流控规则配置
  • ✅ 熔断规则配置
  • ✅ 热点参数限流

4.4 规则持久化到 Nacos

添加依赖

xml 复制代码
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

配置文件

yaml 复制代码
spring:
  cloud:
    sentinel:
      datasource:
        flow:  # 流控规则
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-flow-rules
            groupId: SENTINEL_GROUP
            rule-type: flow

Nacos 创建配置

json 复制代码
[
  {
    "resource": "getUserById",
    "limitApp": "default",
    "grade": 1,
    "count": 10,
    "strategy": 0,
    "controlBehavior": 0
  }
]

五、Gateway + Sentinel 整合

5.1 Gateway 集成 Sentinel

步骤 1:添加依赖
xml 复制代码
<!-- Sentinel Gateway -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
步骤 2:配置限流规则
java 复制代码
@Configuration
public class GatewaySentinelConfig {

    @PostConstruct
    public void initRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        
        // 针对路由限流
        GatewayFlowRule rule = new GatewayFlowRule("user-route")
            .setCount(10)  // QPS = 10
            .setIntervalSec(1);
        
        rules.add(rule);
        GatewayRuleManager.loadRules(rules);
        
        // 配置限流降级处理
        initBlockHandler();
    }

    private void initBlockHandler() {
        GatewayCallbackManager.setBlockHandler((exchange, ex) -> {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 429);
            result.put("msg", "请求过于频繁,请稍后再试");
            
            return ServerResponse
                .status(HttpStatus.TOO_MANY_REQUESTS)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(result));
        });
    }
}

5.2 测试网关限流

bash 复制代码
# 快速请求 20 次
for i in {1..20}; do
  curl http://localhost:9000/user/1001
done

# 前 10 次:正常返回
# 后 10 次:限流返回 429

5.3 OpenFeign 集成 Sentinel

配置文件

yaml 复制代码
feign:
  sentinel:
    enabled: true  # 开启 Feign Sentinel 支持

定义降级类

java 复制代码
@FeignClient(
    name = "user-service",
    fallback = UserClientFallback.class  // 降级类
)
public interface UserClient {
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable Long id);
}

@Component
public class UserClientFallback implements UserClient {
    @Override
    public User getUserById(Long id) {
        // 降级逻辑
        return new User(id, "降级用户", 0, "");
    }
}

六、常见面试题

面试题 1:Gateway 的工作原理是什么?

参考答案

  1. 接收请求
  2. 匹配路由(Predicate)
  3. 执行前置过滤器(鉴权、限流)
  4. 转发请求到目标服务(LoadBalancer 负载均衡)
  5. 接收响应
  6. 执行后置过滤器(添加响应头、日志)
  7. 返回响应

面试题 2:Gateway 和 Zuul 的区别?

参考答案

对比项 Gateway Zuul
技术栈 WebFlux(响应式) Servlet(阻塞式)
性能 一般
维护 ✅ 持续维护 ❌ 停止维护

推荐 :新项目使用 Gateway


面试题 3:什么是熔断?什么是降级?

参考答案

熔断(Circuit Breaker)

  • 当服务故障率达到阈值,自动切断调用
  • 防止雪崩效应

降级(Fallback)

  • 服务不可用时,返回备用响应
  • 保证核心功能可用

关系:熔断是手段,降级是结果


面试题 4:Sentinel 的限流算法有哪些?

参考答案

  1. 快速失败:超过阈值直接拒绝(默认)
  2. Warm Up:预热,逐渐增加流量
  3. 排队等待:匀速排队,削峰填谷

面试题 5:Sentinel 和 Hystrix 的区别?

参考答案

对比项 Sentinel Hystrix
功能 限流 + 熔断 + 系统保护 仅熔断
控制台 ✅ 功能丰富 ❌ 无
维护 ✅ 持续维护 ❌ 停止维护

推荐 :新项目使用 Sentinel


面试题 6:如何实现灰度发布?

参考答案

方案 1:基于权重(Nacos)

复制代码
新版本:权重 10
旧版本:权重 90
→ 10% 流量到新版本

方案 2:基于请求头(Gateway)

yaml 复制代码
predicates:
  - Header=X-Version, v2  # 带 v2 头的请求路由到新版本

面试题 7:Gateway 如何实现跨域?

参考答案

yaml 复制代码
spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods: "*"
            allowedHeaders: "*"

面试题 8:Sentinel 如何持久化规则?

参考答案

方式 1:推送到 Nacos

yaml 复制代码
spring:
  cloud:
    sentinel:
      datasource:
        flow:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-flow-rules

方式 2:推送到 Apollo

方式 3:推送到文件


总结

本文介绍了 Gateway 和 Sentinel 的核心使用:

Gateway :统一网关入口,路由、鉴权、限流

Sentinel :流量控制、熔断降级、系统保护

整合:Gateway + Sentinel 实现网关限流

学习建议

  • 先搭建 Gateway,理解路由和过滤器
  • 再学习 Sentinel,理解限流和熔断
  • 最后整合实践,结合实际场景

🎉 SpringCloud 系列博客完结!从微服务基础到 Gateway + Sentinel,带你全面掌握 SpringCloud 核心技术!

📚 系列回顾

  1. 微服务基础与 SpringCloud 核心作用
  2. 五大核心组件全解析
  3. Nacos 服务注册与发现实战
  4. OpenFeign 服务调用与负载均衡
  5. Gateway 网关与 Sentinel 熔断入门

💡 继续学习

  • SpringCloud Stream(消息驱动)
  • Seata(分布式事务)
  • Sleuth + Zipkin(链路追踪)
相关推荐
一个有温度的技术博主20 小时前
Spring Cloud 入门与实战:从架构拆分到核心组件详解
spring·spring cloud·架构
uNke DEPH21 小时前
SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则
spring cloud·gateway·sentinel
慕容卡卡1 天前
你所不知道的RAG那些事
java·开发语言·人工智能·spring boot·spring cloud
dLYG DUMS1 天前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
ERBU DISH2 天前
当遇到 502 错误(Bad Gateway)怎么办
gateway
Ken_11152 天前
SpringCloud系列(61)--Nacos之服务配置中心的介绍与使用
spring cloud
Ken_11152 天前
SpringCloud系列(62)--Nacos之命名空间、分组和DataID三者之间的关系
spring cloud
Ken_11152 天前
SpringCloud系列(63)--Nacos读取不同配置之DataID配置方案
spring cloud
Devin~Y2 天前
从Spring Boot到Spring AI:音视频AIGC内容社区Java大厂面试三轮连环问(含Kafka/Redis/安全/可观测性答案)
java·spring boot·redis·spring cloud·kafka·spring security·resilience4j
qqty12172 天前
springcloud springboot nacos版本对应
spring boot·spring·spring cloud