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(链路追踪)
相关推荐
无名-CODING3 小时前
SpringCloud 服务注册与发现:Nacos 零基础入门实战
后端·spring·spring cloud
无名-CODING5 小时前
SpringCloud 服务调用与负载均衡:OpenFeign 极简使用教程
spring·spring cloud·负载均衡
会飞的大可6 小时前
022 API网关设计:Gateway路由、限流与鉴权实战
gateway
白露与泡影1 天前
Spring Cloud进阶--分布式权限校验OAuth2
分布式·spring cloud·wpf
晏宁科技YaningAI2 天前
全球短信路由系统设计逻辑打破 80%送达率瓶颈:工程实践拆解
网络·网络协议·架构·gateway·信息与通信·paas
xianjian09122 天前
springboot与springcloud以及springcloudalibaba版本对照
spring boot·后端·spring cloud
ꟼ ꟼ✚19226382 天前
基于 FPGA 的 16QAM 调制解调系统功能说明文档
gateway
.生产的驴2 天前
1Panel实战|SpringColud微服务部署生产环境一键部署Docker+Nacos+MySQL 数据定时备份 控制台 安全高效易维护
服务器·后端·mysql·spring cloud·docker·微服务·信息可视化