《SpringCloud实用版》 Gateway 4.3.x 保姆级实战:路由 + 限流 + 鉴权 + 日志全覆盖

大家好,Spring Cloud 系列第三篇重磅来袭! 上一期《Nacos 从入门到生产级配置》已经打通了服务注册 + 动态配置,今天我们直接上微服务架构的"门面"------Spring Cloud Gateway 4.3.x!为什么 Gateway 是必学?

  • 它是 Spring Cloud 官方唯一推荐的网关(Zuul 早已废弃)
  • Reactive 模型,高并发下性能碾压 Nginx + Zuul
  • 原生支持函数式路由、Bucket4j 限流、JWT 鉴权、日志追踪
  • 阿里、字节、腾讯、美团等大厂统一网关 90%+ 用 Gateway

一、Gateway 2026 年现状 & 为什么选它?

1.1 当前版本

  • 最新稳定版:Spring Cloud Gateway 4.3.x(基于 Spring Boot 3.3.x / 4.0.x,2025 年底发布,2026 年主流)
  • 核心亮点:
    • 函数式路由(RouteLocator + Predicate/ Filter DSL)
    • Bucket4j 原生限流(取代旧 RequestRateLimiter)
    • WebFlux + Reactor 响应式编程
    • 与 Spring Cloud LoadBalancer / Nacos 无缝集成
    • 支持 GraalVM 原生镜像(启动 < 100ms)

1.2 对比其他网关

网关 性能(QPS) 响应式 限流支持 鉴权集成 动态路由 社区活跃 大厂落地 推荐指数
Spring Cloud Gateway 4.x ★★★★★ ★★★★★ ★★★★★ ★★★★★ ★★★★★ ★★★★★ 阿里/字节/腾讯 首选
Zuul 2 ★★★ ★★ ★★★ ★★★ ★★ 旧项目 废弃
Kong ★★★★ ★★★★ ★★★★★ ★★★★★ ★★★★ ★★★★ 国际化 备选
Nginx + Lua ★★★★★ ★★★★ ★★★★ ★★ ★★★★ 高并发 非 Java 团队
Spring Cloud Netflix Zuul 1 ★★ ★★ ★★ 老项目 淘汰

结论:2026 年 Java 微服务项目100% 推荐 Gateway,生态最完整、扩展最强。

二、快速上手:基础网关搭建

2.1 引入依赖(Spring Cloud 2025.1.x + Gateway 4.3.x)xml

复制代码
<!-- Spring Cloud 依赖 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2025.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

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

2.2 配置文件(application.yml)yaml

复制代码
server:
  port: 9000

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true             # 开启服务发现路由
          lower-case-service-id: true
      routes:
        - id: order_route
          uri: lb://order-service   # lb:// + 服务名(Nacos 发现)
          predicates:
            - Path=/order/**
          filters:
            - StripPrefix=1         # 去掉 /order 前缀

2.3 启动类

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

启动后访问:http://localhost:9000/order/discount → 自动转发到 order-service

三、动态路由配置

动态路由:网关从 Nacos/配置中心实时拉取路由规则,服务新增/下线时自动更新路由,无需修改 yml 或重启网关。

3.1 方式一:最推荐 - 结合 Nacos + discovery.locator(自动发现)yaml

复制代码
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true               # 开启服务发现自动路由
          lower-case-service-id: true # 服务名小写(推荐)
          url-expression: "'lb://'+serviceId" # lb:// + 服务名
      routes: []  # 留空,所有路由靠 discovery 自动生成

效果:

  • 所有在 Nacos 注册的服务(如 order-service、user-service)自动生成路由:/order/** → lb://order-service
  • 服务上下线,路由实时自动更新(延迟 < 10s)

3.2 方式二:Nacos 配置中心 + 动态路由(自定义路由规则)

  1. 在 Nacos 控制台新建配置(Data ID:gateway-routes.json,Group:DEFAULT_GROUP,格式:JSON)

    [
    {
    "id": "order_route",
    "uri": "lb://order-service",
    "predicates": [
    {
    "name": "Path",
    "args": {
    "_genkey_0": "/api/order/"
    }
    }
    ],
    "filters": [
    {
    "name": "StripPrefix",
    "args": {
    "_genkey_0": "2"
    }
    }
    ],
    "order": 1
    },
    {
    "id": "user_route",
    "uri": "lb://user-service",
    "predicates": [
    {
    "name": "Path",
    "args": {
    "_genkey_0": "/api/user/
    "
    }
    }
    ],
    "order": 2
    }
    ]

  2. 网关 bootstrap.yml 配置拉取

    spring:
    cloud:
    nacos:
    config:
    server-addr: 127.0.0.1:8848
    file-extension: json
    shared-configs:
    - data-id: gateway-routes.json
    group: DEFAULT_GROUP
    refresh: true

3.自定义 RouteDefinitionLocator 监听配置变更

java 复制代码
@Component
@RefreshScope
public class NacosDynamicRouteDefinitionLocator implements RouteDefinitionLocator {

    private final NacosConfigManager nacosConfigManager;
    private final String dataId = "gateway-routes.json";
    private final String group = "DEFAULT_GROUP";

    public NacosDynamicRouteDefinitionLocator(NacosConfigManager nacosConfigManager) {
        this.nacosConfigManager = nacosConfigManager;
    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        try {
            String content = nacosConfigManager.getConfigService()
                    .getConfig(dataId, group, 5000);
            // 解析 JSON 为 List<RouteDefinition>
            List<RouteDefinition> routes = new ObjectMapper().readValue(content, new TypeReference<>() {});
            return Flux.fromIterable(routes);
        } catch (Exception e) {
            log.error("加载动态路由失败", e);
            return Flux.empty();
        }
    }

    // 监听配置变更,自动刷新
    @EventListener
    public void onRefresh(RefreshEvent event) {
        // 触发路由刷新
        RouteDefinitionRepository repository = ...; // 注入
        // 清空旧路由,加载新路由
    }
}

3.3 方式三:事件驱动动态路由

java 复制代码
@Component
public class DynamicRouteService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteDefinitionRepository routeDefinitionRepository;

    // 从 Nacos 监听配置变更事件
    @NacosConfigListener(dataId = "gateway-routes.json", groupId = "DEFAULT_GROUP")
    public void onRouteConfigChange(String newContent) throws JsonProcessingException {
        List<RouteDefinition> newRoutes = new ObjectMapper().readValue(newContent, new TypeReference<>() {});

        // 清空旧路由
        routeDefinitionRepository.delete(Mono.just("all")).subscribe();

        // 添加新路由
        newRoutes.forEach(route -> 
            routeDefinitionRepository.save(Mono.just(route)).subscribe()
        );

        // 发布刷新事件
        publisher.publishEvent(new RefreshRoutesEvent(this));
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }
}

动态路由流程图

四、全局/路由级限流(Bucket4j + Redis)

4.1 引入依赖xml

复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>8.10.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

4.2 配置 Redis + Bucket4jyaml

复制代码
spring:
  redis:
    host: localhost
    port: 6379

bucket4j:
  gateway:
    enabled: true
    filters:
      - cache-name: gateway-rate-limiter
        # 全局限流:每分钟 100 次
        global:
          capacity: 100
          refill:
            tokens: 100
            period: 1m
        # 路由级限流:/api/order/** 每秒 10 次
        routes:
          order_route:
            capacity: 10
            refill:
              tokens: 10
              period: 1s

4.3 自定义限流响应java

java 复制代码
@Component
public class RateLimiterErrorHandler implements ServerWebExchangeDecorator {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // ... 限流超出返回 429
        return chain.filter(exchange);
    }
}

五、统一鉴权(JWT + OAuth2)

5.1 引入依赖xml

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

5.2 配置 JWT 鉴权 Filteryaml

复制代码
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8080/auth  # 你的授权服务器
          jwk-set-uri: http://localhost:8080/auth/.well-known/jwks.json

5.3 自定义 GlobalFilter 鉴权java

java 复制代码
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class JwtAuthenticationFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String token = request.getHeaders().getFirst("Authorization");

        if (token == null || !token.startsWith("Bearer ")) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // 校验 JWT...
        return chain.filter(exchange);
    }
}

六、全链路日志 + 请求追踪

6.1 开启日志yaml

复制代码
logging:
  level:
    org.springframework.cloud.gateway: TRACE

6.2 自定义请求日志 Filterjava

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

    private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        log.info("Request: {} {} from {}", request.getMethod(), request.getURI(), request.getRemoteAddress());

        return chain.filter(exchange).doOnSuccess(v -> {
            ServerHttpResponse response = exchange.getResponse();
            log.info("Response: {} for {}", response.getStatusCode(), request.getURI());
        });
    }

    @Override
    public int getOrder() {
        return -1; // 最早执行
    }
}

6.3 集成 Micrometer + SkyWalkingxml

复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId> <!-- 实际用 Micrometer Tracing -->
</dependency>

七、生产避坑 & 性能优化

  • 坑1:动态路由不生效 → 确保 @RefreshScope + refresh: true + 监听器正确
  • 坑2:路由冲突 → 优先级:自定义路由 > discovery.locator
  • 坑3:Nacos 配置变更不刷新 → 用 @NacosConfigListener 或事件驱动
  • 优化:路由缓存 + GraalVM + Reactor Netty 线程池调优
  • 监控:Actuator /actuator/gateway/routes 查看当前路由列表

八、总结 & 行动计划

Spring Cloud Gateway 是微服务架构的"门神",掌握它,你就掌握了流量入口的绝对控制权!立即行动:

  1. 跑通基础路由 + Nacos 动态发现
  2. 实现 Bucket4j 限流 + JWT 鉴权
  3. 加全链路日志 + 生产优化

下一期:《Feign + LoadBalancer + Sentinel 微服务调用链路最佳实践》

相关推荐
源代码•宸2 小时前
Golang原理剖析(彻底理解Go语言栈内存/堆内存、Go内存管理)
经验分享·后端·算法·面试·golang·span·mheap
高山上有一只小老虎2 小时前
mybatisplus实现简单的增删改查方法
java·spring boot·后端
ZealSinger2 小时前
Nacos2.x 内存注册表:从服务调用链路深入理解
java·spring boot·spring·spring cloud·nacos
lpfasd1232 小时前
gRPC 协议及其在 Nacos 微服务注册与配置中心中的应用
微服务·云原生·架构
编程彩机2 小时前
互联网大厂Java面试:从微服务到分布式事务的技术深度解析
java·spring cloud·微服务·分布式事务·saga·电商平台
阿蒙Amon2 小时前
C#每日面试题-break、continue和goto的区别
java·面试·c#
葡萄成熟时 !2 小时前
JDK时间类
java·开发语言
长安城没有风2 小时前
Java 高并发核心编程 ----- 初识多线程(下)
java·juc
余瑜鱼鱼鱼2 小时前
Thread类中run和start的区别
java·开发语言·前端