云原生API网关设计与实现方案

发布时间:2026/5/19 3:10:42

云原生API网关设计与实现方案 云原生API网关设计与实现方案一、API网关架构概述API网关是微服务架构中的核心组件负责统一管理所有外部请求提供路由、认证、限流、监控等功能。1.1 网关定位┌─────────────────────────────────────────────────────────────┐ │ 外部客户端 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ API Gateway │ │ ┌─────────┬─────────┬─────────┬─────────┬─────────┐ │ │ │ 路由 │ 认证 │ 限流 │ 监控 │ 熔断 │ │ │ └─────────┴─────────┴─────────┴─────────┴─────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Service A │ │ Service B │ │ Service C │ └─────────────────┘ └─────────────────┘ └─────────────────┘1.2 核心功能功能描述实现方式路由转发请求路由到对应服务路径匹配、权重路由认证授权验证请求合法性JWT、OAuth2、API Key限流熔断保护后端服务令牌桶、熔断器请求聚合合并多个请求GraphQL、批量请求日志监控记录和追踪请求分布式追踪、Metrics二、基于 Spring Cloud Gateway 的实现2.1 网关配置server: port: 8080 spring: cloud: gateway: routes: - id: order-service uri: lb://order-service predicates: - Path/api/orders/** filters: - StripPrefix2 - name: RequestRateLimiter args: key-resolver: #{ipKeyResolver} redis-rate-limiter.replenishRate: 100 redis-rate-limiter.burstCapacity: 200 - id: user-service uri: lb://user-service predicates: - Path/api/users/** - HeaderX-Request-Id, \d filters: - StripPrefix2 - AddRequestHeaderX-Gateway-Id, gateway-01 default-filters: - DedupeResponseHeaderAccess-Control-Allow-Origin, RETAIN_FIRST - RemoveRequestHeaderX-Internal-Secret globalcors: cors-configurations: [/**]: allowedOrigins: * allowedMethods: * allowedHeaders: *2.2 自定义过滤器Component public class AuthFilter implements GatewayFilter, Ordered { private final JwtTokenUtil jwtTokenUtil; Autowired public AuthFilter(JwtTokenUtil jwtTokenUtil) { this.jwtTokenUtil jwtTokenUtil; } Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token exchange.getRequest().getHeaders().getFirst(Authorization); if (token null || !token.startsWith(Bearer )) { return unauthorized(exchange); } String jwtToken token.substring(7); try { Claims claims jwtTokenUtil.parseToken(jwtToken); exchange.getAttributes().put(userId, claims.getSubject()); return chain.filter(exchange); } catch (JwtException e) { return unauthorized(exchange); } } private MonoVoid unauthorized(ServerWebExchange exchange) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } Override public int getOrder() { return -100; } }2.3 动态路由配置Service public class RouteConfigService { private final RouteDefinitionWriter routeDefinitionWriter; private final RouteDefinitionLocator routeDefinitionLocator; Autowired public RouteConfigService(RouteDefinitionWriter writer, RouteDefinitionLocator locator) { this.routeDefinitionWriter writer; this.routeDefinitionLocator locator; } public MonoVoid addRoute(RouteDefinition route) { return routeDefinitionWriter.save(Mono.just(route)).then(); } public MonoVoid updateRoute(String routeId, RouteDefinition route) { return routeDefinitionWriter.delete(Mono.just(routeId)) .then(routeDefinitionWriter.save(Mono.just(route))); } public FluxRouteDefinition getAllRoutes() { return routeDefinitionLocator.getRouteDefinitions(); } }三、基于 Envoy 的服务网格网关3.1 Envoy 配置static_resources: listeners: - name: gateway_listener address: socket_address: address: 0.0.0.0 port_value: 8080 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: type: type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_gateway codec_type: AUTO route_config: name: gateway_route virtual_hosts: - name: all domains: [*] routes: - match: prefix: /api/orders route: cluster: order-service prefix_rewrite: / - match: prefix: /api/users route: cluster: user-service prefix_rewrite: / http_filters: - name: envoy.filters.http.jwt_authn typed_config: type: type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication providers: my_jwt: issuer: https://example.com local_jwks: inline_string: {keys: [...]} rules: - match: prefix: /api/ requires: provider_name: my_jwt - name: envoy.filters.http.router typed_config: {} clusters: - name: order-service connect_timeout: 0.25s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: order-service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: order-service port_value: 80803.2 Rate Limiting 配置http_filters: - name: envoy.filters.http.ratelimit typed_config: type: type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit domain: gateway failure_mode_deny: true rate_limit_service: grpc_service: envoy_grpc: cluster_name: rate_limit_service timeout: 10ms四、API网关安全设计4.1 认证体系Component public class ApiKeyAuthFilter implements GatewayFilter { private static final String API_KEY_HEADER X-API-Key; Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { String apiKey exchange.getRequest().getHeaders().getFirst(API_KEY_HEADER); if (!isValidApiKey(apiKey)) { exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } private boolean isValidApiKey(String apiKey) { // 查询数据库或缓存验证API Key return apiKey ! null apiKeyService.validate(apiKey); } }4.2 请求签名验证public class RequestSignUtil { public static boolean verifySignature(String timestamp, String nonce, String signature, String secret) { String data timestamp nonce secret; String expectedSign DigestUtils.sha256Hex(data); return expectedSign.equals(signature); } public static boolean isTimestampValid(String timestamp, long maxAgeSeconds) { try { long requestTime Long.parseLong(timestamp); long now System.currentTimeMillis() / 1000; return Math.abs(now - requestTime) maxAgeSeconds; } catch (NumberFormatException e) { return false; } } }4.3 WAF 防护Component public class WafFilter implements GatewayFilter { private final SetString blacklist Set.of( script, /script, SELECT, UNION, DROP TABLE ); Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { String body exchange.getRequest().getBody().toString(); for (String pattern : blacklist) { if (body.toUpperCase().contains(pattern)) { exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); return exchange.getResponse().setComplete(); } } return chain.filter(exchange); } }五、网关性能优化5.1 连接池配置Configuration public class HttpClientConfig { Bean public HttpClient httpClient() { return HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) .responseTimeout(Duration.ofSeconds(10)) .pool(PooledConnectionProvider.create( ConnectionPoolConfig.builder() .maxConnections(1000) .pendingAcquireMaxCount(5000) .build() )); } }5.2 缓存策略Component public class CacheFilter implements GatewayFilter { private final CacheManager cacheManager; Autowired public CacheFilter(CacheManager cacheManager) { this.cacheManager cacheManager; } Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { String cacheKey generateCacheKey(exchange.getRequest()); Cache cache cacheManager.getCache(api-cache); if (cache ! null cache.get(cacheKey) ! null) { byte[] cachedResponse cache.get(cacheKey, byte[].class); exchange.getResponse().writeWith(Mono.just( exchange.getResponse().bufferFactory().wrap(cachedResponse) )); return exchange.getResponse().setComplete(); } return chain.filter(exchange).then(Mono.fromRunnable(() - { if (cache ! null shouldCache(exchange)) { byte[] responseBody getResponseBody(exchange); cache.put(cacheKey, responseBody); } })); } }5.3 异步处理Configuration public class AsyncConfig { Bean public AsyncTaskExecutor asyncExecutor() { ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(50); executor.setQueueCapacity(1000); executor.setThreadNamePrefix(gateway-async-); executor.setKeepAliveSeconds(60); executor.initialize(); return executor; } }六、监控与可观测性6.1 Metrics 收集Component public class MetricsFilter implements GatewayFilter { private final MeterRegistry meterRegistry; Autowired public MetricsFilter(MeterRegistry meterRegistry) { this.meterRegistry meterRegistry; } Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { long start System.currentTimeMillis(); String path exchange.getRequest().getPath().value(); return chain.filter(exchange) .doOnSuccess(v - recordMetrics(path, System.currentTimeMillis() - start, 200)) .doOnError(e - recordMetrics(path, System.currentTimeMillis() - start, 500)); } private void recordMetrics(String path, long duration, int status) { Timer.builder(gateway.request.duration) .tag(path, path) .tag(status, String.valueOf(status)) .register(meterRegistry) .record(duration, TimeUnit.MILLISECONDS); Counter.builder(gateway.request.count) .tag(path, path) .tag(status, String.valueOf(status)) .register(meterRegistry) .increment(); } }6.2 分布式追踪Configuration public class TracingConfig { Bean public GatewayFilter tracingFilter(Tracer tracer) { return new TracingGatewayFilter(tracer); } private static class TracingGatewayFilter implements GatewayFilter { private final Tracer tracer; TracingGatewayFilter(Tracer tracer) { this.tracer tracer; } Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { Span span tracer.nextSpan().name(gateway-request).start(); try (Tracer.SpanInScope ws tracer.withSpan(span)) { exchange.getRequest().mutate() .header(X-B3-TraceId, span.context().traceId()) .header(X-B3-SpanId, span.context().spanId()) .build(); return chain.filter(exchange) .doFinally(s - span.finish()); } } } }七、高可用部署7.1 Kubernetes 部署apiVersion: apps/v1 kind: Deployment metadata: name: api-gateway spec: replicas: 3 selector: matchLabels: app: api-gateway template: metadata: labels: app: api-gateway spec: containers: - name: gateway image: api-gateway:latest ports: - containerPort: 8080 resources: limits: cpu: 2 memory: 2Gi requests: cpu: 1 memory: 1Gi livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 10 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: api-gateway spec: type: ClusterIP selector: app: api-gateway ports: - port: 80 targetPort: 80807.2 负载均衡配置apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gateway-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: false nginx.ingress.kubernetes.io/proxy-body-size: 50m nginx.ingress.kubernetes.io/upstream-hash-by: $remote_addr spec: rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-gateway port: number: 80八、最佳实践总结8.1 设计原则单一职责网关只负责路由、认证、限流等横切关注点无状态设计网关不应保存业务状态高性能使用异步非阻塞模型可扩展支持动态路由和插件化架构8.2 安全建议启用 HTTPS强制 TLS 1.2实现请求签名和时间戳验证配置 WAF 规则防止注入攻击定期轮换密钥和证书8.3 性能优化使用连接池复用连接启用响应缓存配置合理的超时时间使用 CDN 加速静态资源通过合理设计和部署API网关可以有效提升微服务架构的安全性、可靠性和可观测性。

相关新闻