java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringCloud Alibaba 服务网关

SpringCloud Alibaba 核心组件解析:服务网关

作者:我登哥MVP

本文介绍了SpringCloud Alibaba中Sentinel与Gateway整合实现网关层限流的方案,通过Gateway进行路由转发,结合Sentinel在网关层对流量进行统一控制,可在请求到达微服务前拦截,感兴趣的朋友一起看看吧

技术栈: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 为什么 — 网关层限流的优势

  1. 请求入口拦截:不让无效请求进入微服务层,节省资源
  2. 统一管理:所有路由规则集中在网关配置,不需要每个微服务各自配
  3. 安全防护:恶意刷量在网关层就被拦截

6.3 怎么做 — 完整实战

6.3.1 项目模块

模块端口说明
clooudalibaba-sentinel-gateway95289528Sentinel + Gateway
cloudalibaba-provider-payment90019001被代理的服务

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-log

6.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 步骤 ④:验证

  1. 启动 Nacos → Gateway(9528) → Provider(9001)
  2. 快速连续访问 http://localhost:9528/pay/nacos/1
  3. 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 版本冲突NoClassDefFoundErroradapter 版本与 sentinel-core 不匹配由 Spring Cloud Alibaba BOM 统一管理版本,不要手动指定

6.8 章节总结

要点说明
三个关键 BeanSentinelGatewayFilter(拦截请求)+ SentinelGatewayBlockExceptionHandler(处理异常)+ GatewayFlowRule(配置规则)
规则配置GatewayFlowRule("routeId").setCount(N).setIntervalSec(S)
自定义响应BlockRequestHandler 返回 JSON,替代默认 HTML
双层防护网关层粗粒度 + 服务层细粒度,组合使用
@Order 很重要HIGHEST_PRECEDENCE 给异常处理器,-1 给过滤器

到此这篇关于SpringCloud Alibaba 核心组件解析:服务网关的文章就介绍到这了,更多相关SpringCloud Alibaba 服务网关内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文