Spring Cloud Gateway实战:微服务API网关从零到一

一、核心概念

  • Route(路由):网关的基本构建块,包含 ID、目标 URI、Predicate、Filter
  • Predicate(断言):匹配请求条件(路径、Header、参数等)
  • Filter(过滤器):对请求进行前置/后置处理(鉴权、限流、日志等)

回到顶部

二、快速搭建

复制代码
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

# application.yml
server:
  port: 8080

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1

      discovery:
        locator:
          enabled: true  # 自动发现服务

回到顶部

三、自定义全局过滤器(JWT 鉴权)

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

    @Override
    public Mono<Void> filter(ServerWebExchange exchange,
                              GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().value();
        // 白名单路径跳过鉴权
        if (path.startsWith("/api/auth/login") ||
            path.startsWith("/api/auth/register")) {
            return chain.filter(exchange);
        }
        String token = exchange.getRequest()
            .getHeaders().getFirst("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        // 验证 JWT(简化示例)
        try {
            String jwt = token.substring(7);
            Claims claims = Jwts.parser()
                .setSigningKey("secret-key").parseClaimsJws(jwt).getBody();
            String userId = claims.getSubject();
            ServerHttpRequest request = exchange.getRequest()
                .mutate().header("X-User-Id", userId).build();
            return chain.filter(exchange.mutate().request(request).build());
        } catch (Exception e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
    }

    @Override
    public int getOrder() { return -100; }
}

回到顶部

四、自定义 GatewayFilter(限流)

复制代码
@Component
public class RateLimitFilter implements GatewayFilter, Ordered {

    private final RateLimiter rateLimiter = RateLimiter.create(100);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange,
                              GatewayFilterChain chain) {
        if (!rateLimiter.tryAcquire()) {
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() { return 0; }
}

# 在路由中使用自定义过滤器
spring.cloud.gateway.routes[0].filters:
  - name: RateLimit
    args:
      redis-rate-limiter.replenishRate: 10
      redis-rate-limiter.burstCapacity: 20

回到顶部

五、跨域配置

复制代码
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

回到顶部

六、网关 vs Nginx

复制代码
# Nginx:反向代理 + 负载均衡
# 适合:静态资源、SSL 终止、四层/七层负载均衡

# Spring Cloud Gateway:业务网关
# 适合:动态路由、JWT 鉴权、限流、熔断、灰度发布

# 生产推荐:Nginx(前置)+ Gateway(后置)
# 请求链路:Client → Nginx → Gateway → Microservice
相关推荐
叶小鸡4 小时前
Java 篇-项目实战-天机学堂(从0到1)-day9
java·开发语言
@#¥&~是乱码鱼啦4 小时前
Spring分层架构:Controller、Service、Mapper数据链路,IOC的真实工作意义
java·spring·架构
xieliyu.4 小时前
Java手搓数据结构:从零模拟实现无头双向非循环链表
java·数据结构·链表
薪火铺子5 小时前
SpringMVC请求处理流程源码解析(第3篇):视图渲染与异常处理
java·后端·spring
逻辑驱动的ken5 小时前
Java高频面试场景题19
java·开发语言·面试·职场和发展·求职招聘
leoufung6 小时前
LeetCode 42:接雨水 —— 从“矩形法”到双指针的完整思考过程
java·算法·leetcode
小碗羊肉6 小时前
【MySQL | 第十一篇】InnoDB引擎
java·数据库·mysql
Dylan的码园6 小时前
Maven基础架构与整体认识
java·junit·maven
弹不出的5h3ll6 小时前
Ghost Bits:高位截断如何让 Java WAF 形同虚设
java·开发语言
庞轩px6 小时前
第七篇:注解与APT深度解析——从@Override到Lombok的底层原理
java·注解·编译·lombok