Spring Cloud Gateway -- 架构图和安全认证,熔断降级等代码示例

一、整体架构图

客户端 → Nginx (负载均衡) → Spring Cloud Gateway → 微服务集群
                      ↑
               服务注册中心 (Eureka/Nacos)

二、详细架构流程图

客户端
Nginx
Spring Cloud Gateway
服务注册中心
微服务A
微服务B
微服务C

让我们通过一个具体的例子来说明整个请求流程:客户端调用 api/userService/userInfo 获取用户信息。

Spring Cloud Gateway 请求调用用户服务的完整流程示例

让我们通过一个具体的例子来说明整个请求流程:客户端调用 api/userService/userInfo 获取用户信息。

三、Nginx 配置示例

upstream gateway {
    server gateway1.example.com:8080;
    server gateway2.example.com:8080;
    keepalive 64;
}

server {
    listen 80;
    server_name api.example.com;
    
    location / {
        proxy_pass http://gateway;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # 长连接优化
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        
        # 超时设置
        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
    }
    
    # 健康检查
    location /health {
        proxy_pass http://gateway/actuator/health;
    }
}

四、Spring Cloud Gateway 最佳实践

1. 基础配置示例

application.yml

spring:
  cloud:
    gateway:
      httpclient:
        pool:
          max-idle-time: 60000
          max-connections: 1000
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY,INTERNAL_SERVER_ERROR
                methods: GET,POST

2. 安全实践

JWT 认证过滤器

@Component
public class JwtAuthFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        
        if (StringUtils.isEmpty(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        
        try {
            // 验证token逻辑
            Claims claims = Jwts.parser()
                .setSigningKey("secret")
                .parseClaimsJws(token.replace("Bearer ", ""))
                .getBody();
            
            // 将用户信息添加到header
            exchange.getRequest().mutate()
                .header("X-User-Id", claims.getSubject())
                .build();
            
            return chain.filter(exchange);
        } catch (Exception e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
    }
}

3. 熔断降级配置

spring:
  cloud:
    gateway:
      routes:
      - id: order-service
        uri: lb://order-service
        predicates:
        - Path=/api/orders/**
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/fallback/order

Fallback 控制器

@RestController
@RequestMapping("/fallback")
public class FallbackController {
    
    @GetMapping("/order")
    public Mono<ResponseEntity<String>> orderFallback() {
        return Mono.just(ResponseEntity
            .status(HttpStatus.SERVICE_UNAVAILABLE)
            .body("Order Service is unavailable. Please try again later."));
    }
}

4. 监控与指标

management:
  endpoints:
    web:
      exposure:
        include: health,info,gateway,metrics
  endpoint:
    health:
      show-details: always
    gateway:
      enabled: true

五、高级实践代码示例

1. 动态路由配置

@Configuration
public class DynamicRouteConfig {
    
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    
    public void addRoute(RouteDefinition definition) {
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
    }
    
    public void deleteRoute(String routeId) {
        routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
    }
}

2. 灰度发布过滤器

@Component
public class GrayReleaseFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String version = exchange.getRequest().getHeaders().getFirst("X-Version");
        
        if ("v2".equals(version)) {
            ServerHttpRequest request = exchange.getRequest().mutate()
                .header("X-Gray", "true")
                .build();
            return chain.filter(exchange.mutate().request(request).build());
        }
        
        return chain.filter(exchange);
    }
}

3. 请求日志过滤器

@Component
@Order(-1)
public class RequestLogFilter implements GlobalFilter {
    
    private static final Logger log = LoggerFactory.getLogger(RequestLogFilter.class);
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long startTime = System.currentTimeMillis();
        String path = exchange.getRequest().getPath().toString();
        
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long duration = System.currentTimeMillis() - startTime;
            int status = exchange.getResponse().getStatusCode() != null ? 
                exchange.getResponse().getStatusCode().value() : 500;
            
            log.info("Request {} - Status: {} - Time: {}ms", 
                path, status, duration);
        }));
    }
}

六、部署建议

  1. 高可用部署

    • 至少部署2个Gateway实例
    • 使用Nginx做负载均衡
  2. 性能优化

    spring:
      cloud:
        gateway:
          httpclient:
            pool:
              max-connections: 1000
              acquire-timeout: 5000
              max-idle-time: 60000
    
  3. 健康检查

    • 配置Kubernetes/ECS的健康检查端点:/actuator/health
    • 设置合理的检查间隔
  4. 日志收集

    • 集成ELK或类似日志系统
    • 记录关键请求信息

七、完整请求流程图

客户端NginxSpring Cloud Gateway服务注册中心(Eureka)用户服务发起请求 GET /api/userService/userInfo转发请求到Gateway查询userService的实例列表返回可用实例(如:192.168.1.10:8081)转发请求 GET /userInfo返回用户数据返回响应返回最终结果客户端NginxSpring Cloud Gateway服务注册中心(Eureka)用户服务
1. 客户端发起请求

客户端发送请求到Nginx入口:

GET http://api.yourdomain.com/api/userService/userInfo
Authorization: Bearer xxxxxx
2. Nginx反向代理

Nginx配置将请求转发到Gateway集群:

location /api/ {
    proxy_pass http://gateway_cluster/;
    # 其他代理配置...
}
3. Gateway接收请求并路由

Gateway路由配置 (application.yml):

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-route
        uri: lb://user-service  # lb表示从服务注册中心获取负载均衡地址
        predicates:
        - Path=/api/userService/**
        filters:
        - StripPrefix=2  # 去掉/api/userService前缀
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 100
            redis-rate-limiter.burstCapacity: 200
4. Gateway处理流程
  1. 路由匹配:Gateway发现请求路径 /api/userService/userInfo 匹配 Path=/api/userService/** 断言
  2. 服务发现:通过lb://user-service从Eureka/Nacos获取用户服务的实际地址(如http://192.168.1.10:8081
  3. 过滤器处理
    • StripPrefix=2 过滤器将路径变为 /userInfo
    • 限流过滤器检查请求频率
    • 如果有其他全局过滤器(如JWT验证)也会执行
  4. 转发请求:Gateway将请求转发到用户服务实例:
    GET http://192.168.1.10:8081/userInfo
    
5. 用户服务处理

用户服务接收到请求:

@RestController
@RequestMapping("/userInfo")
public class UserController {
    
    @GetMapping
    public ResponseEntity<UserInfo> getUserInfo(@RequestHeader("X-User-Id") String userId) {
        // 业务逻辑处理
        UserInfo user = userService.getUserById(userId);
        return ResponseEntity.ok(user);
    }
}
6. 响应返回路径

响应沿原路返回:

用户服务 → Gateway → Nginx → 客户端

关键组件代码示例

1. Gateway全局过滤器(添加用户ID)
@Component
public class AuthFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        
        if (StringUtils.isEmpty(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        
        // 模拟JWT解析
        String userId = parseUserIdFromToken(token);
        
        // 将用户ID添加到header
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header("X-User-Id", userId)
                .build();
        
        return chain.filter(exchange.mutate().request(request).build());
    }
    
    private String parseUserIdFromToken(String token) {
        // 实际项目中使用JWT库解析
        return "12345"; // 模拟返回用户ID
    }
}
2. 用户服务Controller
@RestController
public class UserController {
    
    @GetMapping("/userInfo")
    public Map<String, Object> getUserInfo(
            @RequestHeader("X-User-Id") String userId,
            HttpServletRequest request) {
        
        // 获取实际请求的IP(从Gateway转发)
        String clientIp = request.getHeader("X-Forwarded-For");
        
        return Map.of(
            "userId", userId,
            "username", "user_" + userId,
            "email", userId + "@example.com",
            "requestFrom", clientIp,
            "servicePort", request.getServerPort()
        );
    }
}
3. 测试请求示例

请求:

curl -X GET "http://api.yourdomain.com/api/userService/userInfo" \
-H "Authorization: Bearer mock_token_123"

响应:

{
  "userId": "12345",
  "username": "user_12345",
  "email": "12345@example.com",
  "requestFrom": "客户端真实IP",
  "servicePort": "8081"
}
  1. 统一入口:所有API请求都通过Gateway进入,简化客户端调用
  2. 服务发现:自动发现服务实例,无需硬编码IP
  3. 负载均衡:多个用户服务实例时自动均衡负载
  4. 横切关注点
    • 认证/授权在Gateway统一处理
    • 限流、熔断等保护措施
    • 日志记录和监控
  5. 路径转换:对外暴露友好API,内部服务可使用不同路径

通过这样的架构,你的微服务系统可以获得更好的可维护性、扩展性和安全性。

七、常见问题解决方案

  1. CORS问题
@Bean
public CorsWebFilter corsFilter() {
    return new CorsWebFilter(source -> {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setMaxAge(3600L);
        return config;
    });
}
  1. 大文件上传
spring:
  webflux:
    max-in-memory-size: 10MB
  1. 请求超时
spring:
  cloud:
    gateway:
      httpclient:
        response-timeout: 10s
        connect-timeout: 2s

通过以上配置和实践,Spring Cloud Gateway 可以成为微服务架构中强大的API网关,提供路由、安全、监控等关键功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值