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

 更新时间:2026年06月18日 11:37:57   作者:我登哥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 服务网关内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解SpringMVC中的@RequestMapping注解

    详解SpringMVC中的@RequestMapping注解

    这篇文章主要介绍了SpringMVC中@RequestMapping注解,@RequestMapping注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上,需要的朋友可以参考下
    2023-07-07
  • Java异常类型及处理详情

    Java异常类型及处理详情

    这篇文章主要介绍了Java异常类型及处理, 异常指的是程序在执行过程中,出现了非正常情况,导致了java的jvm停止。感兴趣的小伙伴就和小编一起来学习下面文章的具体内容吧
    2021-09-09
  • Java的super关键字与instanceof运算符使用方法

    Java的super关键字与instanceof运算符使用方法

    这篇文章主要介绍了Java的super关键字与instanceof运算符使用方法,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • guava中Multimap、HashMultimap用法小结

    guava中Multimap、HashMultimap用法小结

    这篇文章主要介绍了guava中Multimap、HashMultimap使用,Multimap它可以很简单的实现一些功能,LinkedHashMultimap实现类与HashMultimap类的实现方法一样,唯一的区别是LinkedHashMultimap保存了记录的插入顺序,本文就这些内容讲解的非常详细,需要的朋友参考下吧
    2022-05-05
  • Java 最优二叉树的哈夫曼算法的简单实现

    Java 最优二叉树的哈夫曼算法的简单实现

    这篇文章主要介绍了Java 最优二叉树的哈夫曼算法的简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • 基于Freemarker和xml实现Java导出word

    基于Freemarker和xml实现Java导出word

    这篇文章主要介绍了基于Freemarker和xml实现Java导出word,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java工具类实现高效编写报表

    Java工具类实现高效编写报表

    对于报表数据大部分情况下使用写sql的方式为大屏/报表提供数据来源,但是对于某些复杂情况下仅仅使用sql无法实现,这篇文章主要介绍了Java工具类实现高效编写报表
    2022-11-11
  • Java嵌套for循环的几种常见优化方案

    Java嵌套for循环的几种常见优化方案

    这篇文章主要给大家介绍了关于Java嵌套for循环的几种常见优化,在Java中优化嵌套for循环可以通过以下几种方式来提高性能和效率,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • Java基于注解实现的锁实例解析

    Java基于注解实现的锁实例解析

    这篇文章主要介绍了Java基于注解实现的锁实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • JAVA注解代码详解一篇就够了

    JAVA注解代码详解一篇就够了

    这篇文章主要介绍了Java注解详细介绍,本文讲解了Java注解是什么、Java注解基础知识、Java注解类型、定义Java注解类型的注意事项等内容,需要的朋友可以参考下
    2021-07-07

最新评论