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
相关推荐
用户1285261160239 分钟前
我把祖传Java项目重构后,接口响应从3s砍到了200ms,只改了这几行代码
java
Linsk44 分钟前
组件 = 模板 + 业务逻辑
java·前端·vue.js
星沉远浦2 小时前
用Gemini高效解决Java代码报错难以定位的问题
java
用户298698530145 小时前
Word 文档字符级格式化:Java 实现方案详解
java·后端
笨鸟飞不快6 小时前
从单个服务到集群:一次完整的性能排查复盘
java·前端
荣码6 小时前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
SamDeepThinking6 小时前
Java微服务练习方式
java·后端·微服务
朦胧之16 小时前
AI 编程-老项目改造篇
java·前端·后端
程序猿大帅21 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
程序员晓琪1 天前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端