← 返回首页
🔧

API网关设计

📂 architecture ⏱ 4 min 697 words

API网关设计

什么是API网关

API网关是微服务架构中的关键组件,它作为客户端与后端服务之间的单一入口点,负责请求路由、协议转换、认证授权、限流熔断等功能。

核心功能

请求路由

将客户端请求路由到相应的后端服务。

# Spring Cloud Gateway路由配置
spring:
  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
        
      - id: product-service
        uri: lb://product-service
        predicates:
        - Path=/api/products/**
        filters:
        - StripPrefix=1

认证授权

在网关层统一处理认证和授权,避免在每个服务中重复实现。

// JWT认证过滤器
@Component
public class JwtAuthenticationFilter implements GlobalFilter, Ordered {
    
    private final JwtTokenValidator tokenValidator;
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");
        
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            return unauthorized(exchange);
        }
        
        String token = authHeader.substring(7);
        
        if (!tokenValidator.validate(token)) {
            return unauthorized(exchange);
        }
        
        Claims claims = tokenValidator.parseToken(token);
        
        // 将用户信息添加到请求头,传递给下游服务
        ServerHttpRequest request = exchange.getRequest().mutate()
            .header("X-User-Id", claims.getSubject())
            .header("X-User-Roles", claims.get("roles", String.class))
            .build();
        
        return chain.filter(exchange.mutate().request(request).build());
    }
    
    private Mono<Void> unauthorized(ServerWebExchange exchange) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }
    
    @Override
    public int getOrder() {
        return -1; // 高优先级
    }
}

// 授权过滤器
@Component
public class AuthorizationFilter implements GlobalFilter, Ordered {
    
    private final AuthorizationService authorizationService;
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
        String roles = exchange.getRequest().getHeaders().getFirst("X-User-Roles");
        String path = exchange.getRequest().getPath().value();
        String method = exchange.getRequest().getMethod().name();
        
        if (!authorizationService.isAuthorized(userId, roles, path, method)) {
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
        }
        
        return chain.filter(exchange);
    }
    
    @Override
    public int getOrder() {
        return 0; // 在认证过滤器之后执行
    }
}

限流熔断

防止后端服务过载,保护系统稳定性。

// 限流配置
@Configuration
public class RateLimitConfig {
    
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getHeaders().getFirst("X-User-Id")
        );
    }
    
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/users/**")
                .filters(f -> f
                    .requestRateLimiter(config -> config
                        .setKeyResolver(userKeyResolver())
                        .setRateLimiter(redisRateLimiter())
                    )
                )
                .uri("lb://user-service"))
            .build();
    }
    
    @Bean
    public RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(10, 20, 1); // 10 requests/sec, burst capacity 20
    }
}

// 熔断器配置
@Configuration
public class CircuitBreakerConfig {
    
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("order-service", r -> r
                .path("/api/orders/**")
                .filters(f -> f
                    .circuitBreaker(config -> config
                        .setName("orderService")
                        .setFallbackUri("forward:/fallback/orders")
                    )
                )
                .uri("lb://order-service"))
            .build();
    }
}

// 熔断降级处理
@RestController
public class FallbackController {
    
    @RequestMapping("/fallback/orders")
    public ResponseEntity<String> ordersFallback() {
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                .body("Order service is currently unavailable. Please try again later.");
    }
}

协议转换

支持不同协议之间的转换,如HTTP到gRPC。

// HTTP到gRPC转换
@Component
public class GrpcConversionFilter implements GlobalFilter, Ordered {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().value();
        
        if (path.startsWith("/grpc/")) {
            // 将HTTP请求转换为gRPC调用
            return handleGrpcRequest(exchange, chain);
        }
        
        return chain.filter(exchange);
    }
    
    private Mono<Void> handleGrpcRequest(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 实现HTTP到gRPC的转换逻辑
        return chain.filter(exchange);
    }
    
    @Override
    public int getOrder() {
        return 1;
    }
}

API聚合

将多个后端服务的响应聚合为一个响应,减少客户端请求次数。

// API聚合控制器
@RestController
@RequestMapping("/api/aggregated")
public class AggregatedController {
    
    private final UserClient userClient;
    private final OrderClient orderClient;
    private final ProductClient productClient;
    
    @GetMapping("/user/{userId}/dashboard")
    public ResponseEntity<UserDashboard> getUserDashboard(@PathVariable Long userId) {
        // 并行调用多个服务
        CompletableFuture<UserDto> userFuture = CompletableFuture.supplyAsync(
            () -> userClient.getUser(userId)
        );
        
        CompletableFuture<List<OrderDto>> ordersFuture = CompletableFuture.supplyAsync(
            () -> orderClient.getOrdersByUser(userId)
        );
        
        CompletableFuture<List<ProductDto>> productsFuture = CompletableFuture.supplyAsync(
            () -> productClient.getRecommendedProducts(userId)
        );
        
        // 等待所有响应
        CompletableFuture.allOf(userFuture, ordersFuture, productsFuture).join();
        
        // 聚合结果
        UserDashboard dashboard = new UserDashboard();
        dashboard.setUser(userFuture.join());
        dashboard.setRecentOrders(ordersFuture.join());
        dashboard.setRecommendedProducts(productsFuture.join());
        
        return ResponseEntity.ok(dashboard);
    }
}

常用技术选型

Spring Cloud Gateway

// Spring Cloud Gateway配置
@Configuration
public class GatewayConfig {
    
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/users/**")
                .filters(f -> f
                    .stripPrefix(1)
                    .addRequestHeader("X-Request-Source", "gateway")
                    .retry(config -> config
                        .setRetries(3)
                        .setBackoff(Duration.ofMillis(100), Duration.ofSeconds(1), 2, true)
                    )
                )
                .uri("lb://user-service"))
            .build();
    }
}

Kong

# Kong路由配置
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rate-limiting
config:
  minute: 100
  policy: local
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: jwt
config:
  uri_param_names: jwt
  header_names: Authorization
---
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: user-service
spec:
  routes:
  - paths:
    - /api/users
    strip_path: true
    plugins:
    - name: rate-limiting
    - name: jwt

Zuul

// Zuul路由配置
@Configuration
public class ZuulConfig {
    
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/users/**")
                .filters(f -> f.stripPrefix(1))
                .uri("lb://user-service"))
            .build();
    }
}

// Zuul过滤器
@Component
public class PreFilter extends ZuulFilter {
    
    @Override
    public String filterType() {
        return "pre";
    }
    
    @Override
    public int filterOrder() {
        return 0;
    }
    
    @Override
    public boolean shouldFilter() {
        return true;
    }
    
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        
        // 添加请求头
        ctx.addZuulRequestHeader("X-Request-Source", "zuul");
        
        return null;
    }
}

高可用设计

集群部署

# Kubernetes部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-gateway
  replicas: 3
spec:
  selector:
    matchLabels:
      app: api-gateway
  template:
    metadata:
      labels:
        app: api-gateway
    spec:
      containers:
      - name: api-gateway
        image: api-gateway:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: 1000m
            memory: 1Gi
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: api-gateway-service
spec:
  selector:
    app: api-gateway
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer

最佳实践

  1. 单一入口:所有外部请求都通过API网关进入
  2. 最小权限:网关只暴露必要的API,不暴露内部服务细节
  3. 统一认证:在网关层统一处理认证授权
  4. 限流熔断:保护后端服务免受过载
  5. 监控日志:记录所有请求和响应,便于调试和审计
  6. 版本管理:支持API版本管理,确保向后兼容
  7. 缓存策略:对频繁访问的数据进行缓存
  8. 错误处理:统一错误响应格式,提供有用的错误信息